Domanda

Come devo ottenere il numero di caratteri di una stringa in C ++?

È stato utile?

Soluzione

Se stai usando un std::string, chiamare length() :

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

Se stai usando un c-string, chiamare strlen() .

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

In alternativa, se vi capita di come l'utilizzo di stringhe in stile Pascal (o F ***** stringhe come Joel Spolsky piace chiamarli quando hanno un NULL finale), solo dereferenziare il primo carattere.

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

Altri suggerimenti

Quando si tratta di stringhe C ++ (std :: string), siete alla ricerca di () o dimensione ) (. Entrambi dovrebbero fornire con lo stesso valore. Tuttavia quando si tratta di stringhe in stile C, è necessario utilizzare 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

Dipende da che tipo di stringa che si sta parlando. Ci sono molti tipi di stringhe:

  1. const char* - una stringa in stile C multibyte
  2. const wchar_t* - una vasta stringa in stile C
  3. std::string - uno "standard" stringa multibyte
  4. std::wstring - uno "standard" a livello di stringa

Per 3 e 4, è possibile utilizzare .size() o .length() metodi.

Per 1, è possibile utilizzare strlen(), ma è necessario assicurarsi che la variabile stringa non è NULL (=== 0)

Per 2, è possibile utilizzare wcslen(), ma è necessario assicurarsi che la variabile stringa non è NULL (=== 0)

Ci sono altri tipi di stringa nelle librerie non standard C ++, come CString di MFC, ATL CComBSTR di, ACE_CString di ACE, e così via, con metodi come .GetLength(), e così via. Non riesco a ricordare le specifiche di tutti diritto al largo della parte superiore della mia testa.

STLSoft biblioteche hanno astratto tutto questo con quello che chiamano accesso stringa spessori , che possono essere utilizzati per ottenere la lunghezza della stringa (e altri aspetti) da qualsiasi tipo. Così, per tutto quanto sopra (compresi quelli di libreria non standard) utilizzando la stessa funzione stlsoft::c_str_len(). questo articolo descrive come funziona il tutto, in quanto non è tutto del tutto ovvio o facile.

Se stai usando vecchio, stringhe in stile C al posto delle corde, STL-stile più recenti, c'è la funzione strlen nella libreria C Tempo di esecuzione:

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

se si sta utilizzando std :: string, ci sono due metodi comuni per questo:

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

se si sta utilizzando la stringa stile C (usando char * o const char *), allora si può usare:

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

.length e .size sono sinonimi, penso solo che "lunghezza" è una parola un po 'più chiara.

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

per un oggetto stringa effettiva:

yourstring.length();

o

yourstring.size();

In C ++ std :: string la lunghezza () e le dimensioni () metodo che dà il numero di byte, e non necessariamente il numero di caratteri!. Stessa cosa con la funzione C-Style sizeof ()!

Per la maggior parte dei personaggi stampabili 7 bit ASCII questo è lo stesso valore, ma per i caratteri che non sono a 7 bit-ASCII non è sicuramente. Vedere l'esempio seguente per dare risultati reali (64 bit linux).

Non c'è semplice / funzione C C ++ che può davvero contare il numero di caratteri. Tra l'altro, tutte queste cose dipende dall'implementazione e possono essere diverse per altri ambienti (compilatore, vincere 16/32, Linux, embedded, ...)

Vedere esempio seguente:

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

L'output dell'esempio è questo:

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

più semplice modo per ottenere la lunghezza di corda senza preoccuparsi std namespace è la seguente

stringa con / senza spazi

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

stringa senza spazi

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

Per Unicode

Diverse risposte qui hanno affrontato che .length() dà i risultati sbagliati con caratteri multibyte, ma ci sono 11 risposte e nessuno di loro hanno fornito una soluzione.

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

Prima di tutto, è importante sapere che cosa si intende per "lunghezza". Per un esempio motivante, si consideri la stringa "Z͉̳̺ͥͬ̾a̴͕̒̒͌̋ͪl̨͎̰̘͉̟ͤ̈̚͜g͕͔̤͖̟̒͝o̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚" (si noti che alcune lingue, in particolare Thai, utilizzano effettivamente combinare i segni diacritici, quindi questo non è solo utile per 15 anni memi, ma ovviamente questo è il più importante caso d'uso). Si supponga che è messo nel UTF-8 . Ci sono 3 modi in cui possiamo parlare circa la lunghezza di questa stringa:

95 byte

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 grafemi

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

Trovare le lunghezze utilizzando ICU

Ci sono classi C ++ per terapia intensiva, ma richiedono la conversione in UTF-16. È possibile utilizzare i tipi C e le macro direttamente per ottenere qualche supporto 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̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚");
}

Questo stampa:

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 avvolge ICU, e potrebbe fornire un'interfaccia più gradevole. Tuttavia, esso richiede ancora la conversione da / UTF-16.

Potrebbe essere il modo più semplice per inserire una stringa e trovare la sua lunghezza.

// 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());

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top