Pergunta

Como devo obter o número de caracteres em uma cadeia em C ++?

Foi útil?

Solução

Se você estiver usando uma std::string, chamar length() :

std::string str = "hello";
std::cout << str << ":" << str.length();
// Outputs "hello:5"

Se você estiver usando uma c-string, chame strlen() .

const char *str = "hello";
std::cout << str << ":" << strlen(str);
// Outputs "hello:5"

Ou, se acontecer de você como o uso de cordas de estilo Pascal (ou f ***** cordas como Joel Spolsky gosta de chamá-los quando eles têm um NULL à direita), basta excluir a referência o primeiro caractere.

const char *str = "\005hello";
std::cout << str + 1 << ":" << *str;
// Outputs "hello:5"

Outras dicas

Ao lidar com strings C ++ (std :: string), que você está procurando () ou tamanho () . Ambos devem fornecê-lo com o mesmo valor. No entanto quando se trata de C-estilo cordas, você usaria strlen () .

#include <iostream>
#include <string.h>

int main(int argc, char **argv)
{
   std::string str = "Hello!";
   const char *otherstr = "Hello!"; // C-Style string
   std::cout << str.size() << std::endl;
   std::cout << str.length() << std::endl;
   std::cout << strlen(otherstr) << std::endl; // C way for string length
   std::cout << strlen(str.c_str()) << std::endl; // convert C++ string to C-string then call strlen
   return 0;
}

Output:

6
6
6
6

Depende de que tipo string que você está falando. Existem muitos tipos de strings:

  1. const char* - uma string de estilo C multibyte
  2. const wchar_t* - uma ampla cadeia de estilo C
  3. std::string - uma string multibyte "padrão"
  4. std::wstring - uma cadeia ampla "padrão"

Para 3 e 4, você pode usar métodos .size() ou .length().

Para 1, você pode usar strlen(), mas você deve garantir que a variável de cadeia não é NULL (=== 0)

Para 2, você pode usar wcslen(), mas você deve garantir que a variável de cadeia não é NULL (=== 0)

Existem outros tipos de cordas em bibliotecas não-padrão C ++, como CString do MFC, CComBSTR do ATL, ACE_CString da ACE, e assim por diante, com métodos como .GetLength(), e assim por diante. Não me lembro os detalhes de todos eles direita fora do topo da minha cabeça.

O STLSoft bibliotecas têm abstraída isso tudo com o que eles chamam de calços de acesso corda , que pode ser usado para obter o comprimento da corda (e outros aspectos) de qualquer tipo. Assim, para todos os itens acima (incluindo os de biblioteca não-padrão) usando a mesma função stlsoft::c_str_len(). Este artigo descreve como tudo funciona, como nem tudo é totalmente óbvia ou fácil.

Se você estiver usando velho, corda de estilo C em vez das, cordas de estilo STL mais recentes, há a função strlen na biblioteca C tempo de execução:

const char* p = "Hello";
size_t n = strlen(p);

Se você estiver usando std :: string, existem dois métodos comuns para que:

std::string Str("Some String");
size_t Size = 0;
Size = Str.size();
Size = Str.length();

Se você estiver usando a corda estilo C (usando char * ou const char *), então você pode usar:

const char *pStr = "Some String";
size_t Size = strlen(pStr);
string foo;
... foo.length() ...

.length e .size são sinônimos, eu só acho que "comprimento" é uma palavra um pouco mais clara.

std::string str("a string");
std::cout << str.size() << std::endl;

para um objeto seqüência real:

yourstring.length();

ou

yourstring.size();

Em C ++ std :: string o comprimento () e tamanho () método dá-lhe o número de bytes, e não necessariamente o número de caracteres!. Mesmo com a função do c-Style sizeof ()!

Para a maioria dos personagens 7bit-ASCII imprimíveis este é o mesmo valor, mas para personagens que não são 7bit-ASCII definitivamente não é. Veja o seguinte exemplo para lhe dar resultados reais (64 bits linux).

Não há simples / c ++ função c que realmente pode contar o número de caracteres. By the way, todo este material é dependente de implementação e pode ser diferente em outros ambientes (compilador, ganhar 16/32, linux, incorporado, ...)

Veja o exemplo seguinte:

#include <string>
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

int main()
{
/* c-Style char Array */
const char * Test1 = "1234";
const char * Test2 = "ÄÖÜ€";
const char * Test3 = "αβγ𝄞";

/* c++ string object */
string sTest1 = "1234";
string sTest2 = "ÄÖÜ€";
string sTest3 = "αβγ𝄞";

printf("\r\nC Style Resluts:\r\n");
printf("Test1: %s, strlen(): %d\r\n",Test1, (int) strlen(Test1));
printf("Test2: %s, strlen(): %d\r\n",Test2, (int) strlen(Test2));
printf("Test3: %s, strlen(): %d\r\n",Test3, (int) strlen(Test3));

printf("\r\nC++ Style Resluts:\r\n");
cout << "Test1: " << sTest1 << ", Test1.size():  " <<sTest1.size() <<"  sTest1.length(): " << sTest1.length() << endl;
cout << "Test1: " << sTest2 << ", Test2.size():  " <<sTest2.size() <<"  sTest1.length(): " << sTest2.length() << endl;
cout << "Test1: " << sTest3 << ", Test3.size(): " <<sTest3.size() << "  sTest1.length(): " << sTest3.length() << endl;
return 0;
}

A saída do exemplo é esta:

C Style Results:
Test1: ABCD, strlen(): 4    
Test2: ÄÖÜ€, strlen(): 9
Test3: αβγ𝄞, strlen(): 10

C++ Style Results:
Test1: ABCD, sTest1.size():  4  sTest1.length(): 4
Test2: ÄÖÜ€, sTest2.size():  9  sTest2.length(): 9
Test3: αβγ𝄞, sTest3.size(): 10  sTest3.length(): 10

Maneira mais simples para obter o comprimento de corda sem se preocupar com namespace std é a seguinte

string com / sem espaços

#include <iostream>
#include <string>
using namespace std;
int main(){
    string str;
    getline(cin,str);
    cout<<"Length of given string is"<<str.length();
    return 0;
}

string sem espaços

#include <iostream>
#include <string>
using namespace std;
int main(){
    string str;
    cin>>str;
    cout<<"Length of given string is"<<str.length();
    return 0;
}

Para Unicode

Várias respostas aqui têm abordado que .length() dá os resultados errados com caracteres de vários bytes, mas existem 11 respostas e nenhum deles forneceu uma solução.

O caso de Z??????a???????l???????¨??g???????o???????¯????

Em primeiro lugar, é importante saber o que você quer dizer com "comprimento". Para um exemplo de motivação, considere a string "Z??????a???????l???????¨??g???????o???????¯????" (note que algumas línguas, nomeadamente tailandesa, realmente usar combinar sinais diacríticos, então isso não apenas útil para memes 15 anos de idade, mas, obviamente, é esse é o caso de uso mais importante). Suponha que está codificado em UTF-8 . Há 3 maneiras podemos falar sobre o comprimento dessa seqüência:

95 bytes

00000000: 5acd a5cd accc becd 89cc b3cc ba61 cc92  Z............a..
00000010: cc92 cd8c cc8b cdaa ccb4 cd95 ccb2 6ccd  ..............l.
00000020: a4cc 80cc 9acc 88cd 9ccc a8cd 8ecc b0cc  ................
00000030: 98cd 89cc 9f67 cc92 cd9d cd85 cd95 cd94  .....g..........
00000040: cca4 cd96 cc9f 6fcc 90cd afcc 9acc 85cd  ......o.........
00000050: aacc 86cd a3cc a1cc b5cc a1cc bccd 9a    ...............

50 codepoints

LATIN CAPITAL LETTER Z
COMBINING LEFT ANGLE BELOW
COMBINING DOUBLE LOW LINE
COMBINING INVERTED BRIDGE BELOW
COMBINING LATIN SMALL LETTER I
COMBINING LATIN SMALL LETTER R
COMBINING VERTICAL TILDE
LATIN SMALL LETTER A
COMBINING TILDE OVERLAY
COMBINING RIGHT ARROWHEAD BELOW
COMBINING LOW LINE
COMBINING TURNED COMMA ABOVE
COMBINING TURNED COMMA ABOVE
COMBINING ALMOST EQUAL TO ABOVE
COMBINING DOUBLE ACUTE ACCENT
COMBINING LATIN SMALL LETTER H
LATIN SMALL LETTER L
COMBINING OGONEK
COMBINING UPWARDS ARROW BELOW
COMBINING TILDE BELOW
COMBINING LEFT TACK BELOW
COMBINING LEFT ANGLE BELOW
COMBINING PLUS SIGN BELOW
COMBINING LATIN SMALL LETTER E
COMBINING GRAVE ACCENT
COMBINING DIAERESIS
COMBINING LEFT ANGLE ABOVE
COMBINING DOUBLE BREVE BELOW
LATIN SMALL LETTER G
COMBINING RIGHT ARROWHEAD BELOW
COMBINING LEFT ARROWHEAD BELOW
COMBINING DIAERESIS BELOW
COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW
COMBINING PLUS SIGN BELOW
COMBINING TURNED COMMA ABOVE
COMBINING DOUBLE BREVE
COMBINING GREEK YPOGEGRAMMENI
LATIN SMALL LETTER O
COMBINING SHORT STROKE OVERLAY
COMBINING PALATALIZED HOOK BELOW
COMBINING PALATALIZED HOOK BELOW
COMBINING SEAGULL BELOW
COMBINING DOUBLE RING BELOW
COMBINING CANDRABINDU
COMBINING LATIN SMALL LETTER X
COMBINING OVERLINE
COMBINING LATIN SMALL LETTER H
COMBINING BREVE
COMBINING LATIN SMALL LETTER A
COMBINING LEFT ANGLE ABOVE

5 grafemas

Z with some s**t
a with some s**t
l with some s**t
g with some s**t
o with some s**t

Encontrar os comprimentos usando UTI

Existem classes C ++ para UTI, mas exigem a conversão para UTF-16. Você pode usar os tipos C e macros diretamente para obter algum apoio UTF-8:

#include <memory>
#include <iostream>
#include <unicode/utypes.h>
#include <unicode/ubrk.h>
#include <unicode/utext.h>

//
// C++ helpers so we can use RAII
//
// Note that ICU internally provides some C++ wrappers (such as BreakIterator), however these only seem to work
// for UTF-16 strings, and require transforming UTF-8 to UTF-16 before use.
// If you already have UTF-16 strings or can take the performance hit, you should probably use those instead of
// the C functions. See: http://icu-project.org/apiref/icu4c/
//
struct UTextDeleter { void operator()(UText* ptr) { utext_close(ptr); } };
struct UBreakIteratorDeleter { void operator()(UBreakIterator* ptr) { ubrk_close(ptr); } };
using PUText = std::unique_ptr<UText, UTextDeleter>;
using PUBreakIterator = std::unique_ptr<UBreakIterator, UBreakIteratorDeleter>;

void checkStatus(const UErrorCode status)
{
    if(U_FAILURE(status))
    {
        throw std::runtime_error(u_errorName(status));
    }
}

size_t countGraphemes(UText* text)
{
    // source for most of this: http://userguide.icu-project.org/strings/utext
    UErrorCode status = U_ZERO_ERROR;
    PUBreakIterator it(ubrk_open(UBRK_CHARACTER, "en_us", nullptr, 0, &status));
    checkStatus(status);
    ubrk_setUText(it.get(), text, &status);
    checkStatus(status);
    size_t charCount = 0;
    while(ubrk_next(it.get()) != UBRK_DONE)
    {
        ++charCount;
    }
    return charCount;
}

size_t countCodepoints(UText* text)
{
    size_t codepointCount = 0;
    while(UTEXT_NEXT32(text) != U_SENTINEL)
    {
        ++codepointCount;
    }
    // reset the index so we can use the structure again
    UTEXT_SETNATIVEINDEX(text, 0);
    return codepointCount;
}

void printStringInfo(const std::string& utf8)
{
    UErrorCode status = U_ZERO_ERROR;
    PUText text(utext_openUTF8(nullptr, utf8.data(), utf8.length(), &status));
    checkStatus(status);

    std::cout << "UTF-8 string (might look wrong if your console locale is different): " << utf8 << std::endl;
    std::cout << "Length (UTF-8 bytes): " << utf8.length() << std::endl;
    std::cout << "Length (UTF-8 codepoints): " << countCodepoints(text.get()) << std::endl;
    std::cout << "Length (graphemes): " << countGraphemes(text.get()) << std::endl;
    std::cout << std::endl;
}

void main(int argc, char** argv)
{
    printStringInfo(u8"Hello, world!");
    printStringInfo(u8"หวัดดีชาวโลก");
    printStringInfo(u8"\xF0\x9F\x90\xBF");
    printStringInfo(u8"Z͉̳̺ͥͬ̾a̴͕̲̒̒͌̋ͪl̨͎̰̘͉̟ͤ̀̈̚͜g͕͔̤͖̟̒͝ͅo̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚");
}

Esta impressões:

UTF-8 string (might look wrong if your console locale is different): Hello, world!
Length (UTF-8 bytes): 13
Length (UTF-8 codepoints): 13
Length (graphemes): 13

UTF-8 string (might look wrong if your console locale is different): หวัดดีชาวโลก
Length (UTF-8 bytes): 36
Length (UTF-8 codepoints): 12
Length (graphemes): 10

UTF-8 string (might look wrong if your console locale is different): 🐿
Length (UTF-8 bytes): 4
Length (UTF-8 codepoints): 1
Length (graphemes): 1

UTF-8 string (might look wrong if your console locale is different): Z͉̳̺ͥͬ̾a̴͕̲̒̒͌̋ͪl̨͎̰̘͉̟ͤ̀̈̚͜g͕͔̤͖̟̒͝ͅo̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚
Length (UTF-8 bytes): 95
Length (UTF-8 codepoints): 50
Length (graphemes): 5

Boost.Locale wraps UTI, e pode fornecer uma interface mais agradável. No entanto, ainda requer a conversão de / para UTF-16.

Pode ser a maneira mais fácil de introduzir uma cadeia e encontrar o seu comprimento.

// Finding length of a string in C++ 
#include<iostream>
#include<string>
using namespace std;

int count(string);

int main()
{
string str;
cout << "Enter a string: ";
getline(cin,str);
cout << "\nString: " << str << endl;
cout << count(str) << endl;

return 0;

}

int count(string s){
if(s == "")
  return 0;
if(s.length() == 1)
  return 1;
else
    return (s.length());

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top