简体   繁体   中英

Unexpected strlen result for a string literal

#include <iostream>
#include <cstring>

int main()
{   
    auto l = std::strlen("123\0456\0");
    std::cout << l << std::endl;
}

Why is the output of this code 5?

I expected 3.

Here is an online version to test: https://ideone.com/UQRKlV

"123\\0456\\0" is a literal of type const char[7] .

\\045 is a single character, specified in octal. In ASCII it's '%' . Here \\0 is not denoting NUL since the maximal munch parsing rules extract \\045 as an octal escape sequence : note that 0, 4, and 5 are valid octal digits and that an octal escape sequence cannot be longer than 3 digits.

The second \\0 is an explicit NUL , and there's an implied extra NUL at the end of the literal.

strlen will return 5 since there are that many characters before the first NUL .

Characters in a literal can be escaped using either hex ( \\xNN ), octal ( \\0NN ), or Unicode ( \\uNNNN , \\UNNNNNNNN ) notation.

In your string literal, "123\\0456\\0" , \\045 and \\0 are OCTAL escape sequences.

You are expecting the compiler to parse the 1st \\0 as a 1-digit octal sequence for a NUL terminator, but it is actually parsed as a 3-digit octal sequence instead, because octal uses up to 3 digits max, and 0, 4, and 5 are valid octal digits. So the compiler will parse the 3-digit \\045 sequence as a single char having a numeric value of octal 45 (decimal 37, hex 0x25), which in most (not all) charsets is the ASCII % character, and it will parse the 2nd 1-digit \\0 sequence as a single char having a numeric value of octal 0 (decimal 0, hex 0x00), which in all charsets is a NUL character.

So, "123\\0456\\0" has 7 char s total (including the implicit null terminator at the end):

1 2 3 % 6 NUL NUL

strlen() will count char s until it encounters a NUL character. Which is why the output is 5, not 3.

First read about string literals in C++ . Look for special meaning of escape sequences .

Then read what strlen does and combine this knowledge to explain outcome.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM