[c++] How to get the number of characters in a std::string?

How should I get the number of characters in a string in C++?

This question is related to c++ string stdstring string-length

The answer is


In C++ std::string the length() and size() method gives you the number of bytes, and not necessarily the number of characters !. Same with the c-Style sizeof() function!

For most of the printable 7bit-ASCII Characters this is the same value, but for characters that are not 7bit-ASCII it's definitely not. See the following example to give you real results (64bit linux).

There is no simple c/c++ function that can really count the number of characters. By the way, all of this stuff is implementation dependent and may be different on other environments (compiler, win 16/32, linux, embedded, ...)

See following example:

#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 = "aß?";

/* c++ string object */
string sTest1 = "1234";
string sTest2 = "ÄÖÜ€";
string sTest3 = "aß?";

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

The output of the example is this:

C Style Results:
Test1: ABCD, strlen(): 4    
Test2: ÄÖÜ€, strlen(): 9
Test3: aß?, strlen(): 10

C++ Style Results:
Test1: ABCD, sTest1.size():  4  sTest1.length(): 4
Test2: ÄÖÜ€, sTest2.size():  9  sTest2.length(): 9
Test3: aß?, sTest3.size(): 10  sTest3.length(): 10

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

string foo;
... foo.length() ...

.length and .size are synonymous, I just think that "length" is a slightly clearer word.


It depends on what string type you're talking about. There are many types of strings:

  1. const char* - a C-style multibyte string
  2. const wchar_t* - a C-style wide string
  3. std::string - a "standard" multibyte string
  4. std::wstring - a "standard" wide string

For 3 and 4, you can use .size() or .length() methods.

For 1, you can use strlen(), but you must ensure that the string variable is not NULL (=== 0)

For 2, you can use wcslen(), but you must ensure that the string variable is not NULL (=== 0)

There are other string types in non-standard C++ libraries, such as MFC's CString, ATL's CComBSTR, ACE's ACE_CString, and so on, with methods such as .GetLength(), and so on. I can't remember the specifics of them all right off the top of my head.

The STLSoft libraries have abstracted this all out with what they call string access shims, which can be used to get the string length (and other aspects) from any type. So for all of the above (including the non-standard library ones) using the same function stlsoft::c_str_len(). This article describes how it all works, as it's not all entirely obvious or easy.


For Unicode

Several answers here have addressed that .length() gives the wrong results with multibyte characters, but there are 11 answers and none of them have provided a solution.

The case of Z??????a???????_l?`?¨???????g????????o???¯????????

First of all, it's important to know what you mean by "length". For a motivating example, consider the string "Z??????a???????_l?`?¨???????g????????o???¯????????" (note that some languages, notably Thai, actually use combining diacritical marks, so this isn't just useful for 15-year-old memes, but obviously that's the most important use case). Assume it is encoded in UTF-8. There are 3 ways we can talk about the length of this string:

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 graphemes

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

Finding the lengths using ICU

There are C++ classes for ICU, but they require converting to UTF-16. You can use the C types and macros directly to get some UTF-8 support:

#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???¯????????");
}

This prints:

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 ICU, and might provide a nicer interface. However, it still requires conversion to/from UTF-16.


if you're using std::string, there are two common methods for that:

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

if you're using the C style string (using char * or const char *) then you can use:

const char *pStr = "Some String";
size_t Size = strlen(pStr);

Simplest way to get length of string without bothering about std namespace is as follows

string with/without spaces

#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 without spaces

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

for an actual string object:

yourstring.length();

or

yourstring.size();

It might be the easiest way to input a string and find its length.

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

}

When dealing with C++ strings (std::string), you're looking for length() or size(). Both should provide you with the same value. However when dealing with C-Style strings, you would use 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

If you're using old, C-style string instead of the newer, STL-style strings, there's the strlen function in the C run time library:

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

Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to stdstring

Is it possible to use std::string in a constexpr? Error: invalid operands of types ‘const char [35]’ and ‘const char [2]’ to binary ‘operator+’ Remove First and Last Character C++ Concatenating strings doesn't work as expected What does string::npos mean in this code? How to replace all occurrences of a character in string? std::string formatting like sprintf convert a char* to std::string How to get the number of characters in a std::string? c++ integer->std::string conversion. Simple function?

Examples related to string-length

String field value length in mongoDB SQL SELECT everything after a certain character Length of string in bash Get column value length, not column max length of value How to get the number of characters in a string How to find the length of a string in R Retrieve the maximum length of a VARCHAR column in SQL Server Measure string size in Bytes in php How to get the size of a string in Python? Display only 10 characters of a long string?