Pregunta

¿Cómo debería obtener el número de caracteres de una cadena en C ++?

¿Fue útil?

Solución

Si estás usando un std::string, llame length() :

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

Si estás usando un C-string, llame strlen() .

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

O, si sucede que como el uso de cadenas de estilo Pascal (o F ***** cadenas como Joel Spolsky le gusta llamarles cuando tienen un valor NULL al final), simplemente eliminar la referencia al primer carácter.

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

Otros consejos

Cuando se trata de cadenas de C ++ (std :: string), que busca () o tamaño () . Ambos se debe proporcionar con el mismo valor. Sin embargo cuando se trata de cadenas estilo C, se usaría 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;
}

Salida:

6
6
6
6

Depende de qué tipo de cadena que está hablando. Hay muchos tipos de cadenas:

  1. const char* - una cadena multibyte de estilo C
  2. const wchar_t* - una amplia cadena tipo C
  3. std::string - una cadena multibyte "estándar"
  4. std::wstring - una cadena amplia "estándar"

Para 3 y 4, puede utilizar métodos .size() o .length().

Para 1, puede utilizar strlen(), pero debe asegurarse de que la variable de cadena no es NULL (=== 0)

Para 2, puede utilizar wcslen(), pero debe asegurarse de que la variable de cadena no es NULL (=== 0)

Hay otros tipos de cadenas en las bibliotecas no estándar de C ++, tales como CString de MFC, CComBSTR de ATL, ACE_CString de ACE, y así sucesivamente, con métodos tales como .GetLength(), y así sucesivamente. No puedo recordar los detalles de todo derecho a retirarse de la parte superior de la cabeza.

Las bibliotecas STLSoft han abstraído todo esto con lo que ellos llaman cuñas de acceso cadena , que puede ser utilizado para obtener la longitud de cadena (y otros aspectos) de cualquier tipo. Así, por todo lo anterior (incluyendo las bibliotecas no estándar) utilizando el mismo stlsoft::c_str_len() función. En este artículo se describe cómo funciona todo, ya que no todo es del todo evidente o fácil.

Si está utilizando edad, cadena tipo C en lugar de las cuerdas, de estilo STL más recientes, está la función strlen en la biblioteca de tiempo de ejecución C:

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

si está utilizando std :: string, hay dos métodos comunes para que:

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

si está utilizando la cadena estilo C (utilizando char * o const char *), entonces usted puede utilizar:

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

.length y .size son sinónimos, simplemente creo que "longitud" es una palabra un poco más claro.

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

para un objeto cadena real:

yourstring.length();

o

yourstring.size();

En C ++ std :: string la longitud () y el tamaño () método le da el número de bytes, y no necesariamente el número de caracteres!. Lo mismo con la función de c-estilo sizeof ()!

Para la mayoría de los caracteres imprimibles ASCII de 7 bits, este es el mismo valor, pero para caracteres que no son ASCII de 7 bits-definitivamente no es. Véase el siguiente ejemplo para dar resultados reales (Linux de 64 bits).

No hay sencilla / c función de C ++ que realmente puede contar el número de caracteres. Por cierto, todas estas cosas depende de la implementación y pueden ser diferentes en otros entornos (compilador, ganar 16/32, Linux embebido, ...)

Ver siguiente ejemplo:

#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;
}

La salida del ejemplo es la siguiente:

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

La manera más sencilla de obtener la longitud de la cadena sin preocuparse de espacio de nombres std es el siguiente

string con / sin espacios

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

cadena sin espacios

#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

Varias respuestas aquí se han ocupado de que .length() da los resultados incorrectos con caracteres de varios bytes, pero hay 11 respuestas y ninguno de ellos ha proporcionado una solución.

El caso de Z͉̳̺ͥͬ̾a̴͕̒̒͌̋ͪl̨͎̰̘͉̟ͤ̈̚͜g͕͔̤͖̟̒͝o̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚

En primer lugar, es importante saber qué quiere decir con "longitud". Para un ejemplo motivador, considere la cadena "Z͉̳̺ͥͬ̾a̴͕̒̒͌̋ͪl̨͎̰̘͉̟ͤ̈̚͜g͕͔̤͖̟̒͝o̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚" (tenga en cuenta que algunos idiomas, en particular tailandés, el uso en combinación diacrítica realidad, así que esto no es solo útil para los memes de 15 años de edad, pero, obviamente, ese es el caso de uso más importante). Asuma que se codifica en UTF-8 . Hay 3 formas en que podemos hablar de la longitud de esta cadena:

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 puntos de código

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 las longitudes utilizando ICU

Hay clases de C ++ para la UCI, pero requieren la conversión a UTF-16. Se pueden utilizar los tipos C y macros directamente a conseguir un poco de soporte 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̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚");
}

Esto imprime:

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 envuelve la UCI, y podría proporcionar una interfaz más agradable. Sin embargo, todavía requiere la conversión a / desde UTF-16.

Puede ser que sea la forma más fácil de entrada una cadena y encontrar su longitud.

// 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top