Why printing out the characters “” (147, 148 ascii) does not work as expected on c++?

Viewed 104

I do not understand what's going on here. This is compiled with GCC 10.2.0 compiler. Printing out the whole string is different than printing out each character.

#include <iostream>

int main(){
   char str[] = "“”";
   std::cout << str << std::endl;
   std::cout << str[0] << str[1] << std::endl;
}

Output

“”
��

Why are not the two outputted lines the same? I would expect the same line twice. Printing out alphanumeric characters does output the same line twice.

2 Answers

"“”" contains more bytes than you think. It's usually encoded as utf8. To see that, you can print the size of the array:

std::cout << sizeof str << '\n';

Prints 7 in my testing. Utf8 is a multi-byte encoding. That means each character is encoded in multiple bytes. Now, you're printing bytes of a utf8 encoded string, which are not printable themselves. That's why you get � when you try to print them.

Bear in mind that, on almost all systems, the maximum value a (signed) char can hold is 127. So, more likely than not, your two 'special' characters are actually being encoded as multi-byte combinations.

In such a case, passing the string pointer to std::cout will keep feeding data from that buffer until a zero (nul-terminator) byte is encountered. Further, it appears that, on your system, the std::cout stream can properly interpret multi-byte character sequences, so it shows the expected characters.

However, when you pass the individual char elements, as str[0] and str[1], there is no possibility of parsing those arguments as components of multi-byte characters: each is interpreted 'as-is', and those values do not correspond to valid, printable characters, so the 'weird' � symbol is shown, instead.

Related