Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Null character when using range-based loop over temporary string?

Tags:

c++

string

c++11

When I loop over a temporary std::string (rvalue?) using a range-based for loop, there seems to be an extra character, the null terminator \0.

When the string is not temporary (lvalue instead?), there is no extra character. Why?

    std::map<char, int> m;

    for (char c : "bar") m[c] = 0;

    for (auto [c, f] : m) {
        if (c == '\0') std::cout << "this is a null char, backward slash zero" << std::endl;
        std::cout << c << std::endl; 
    }

Output:

this is a null char, backward slash zero

a
b
r

(note the empty line, where the \0 is being printed)

Compared to:

    std::map<char,int> m;
    
    std::string s = "bar";
    
    for (char c : s) m[c] = 0;    
    
    for (auto [c, f] : m) {
        if (c == '\0') std::cout << "this is a null char, backward slash zero" << std::endl;
        std::cout << c << std::endl; 
    }

Output:

a
b
r
like image 220
Justin Avatar asked Mar 09 '26 10:03

Justin


1 Answers

Because "bar" is not a std::string, but a char array (const char[4]) containing 4 elements, including the last null character. I.e. c-style string literal:

The null character ('\0', L'\0', char16_t(), etc) is always appended to the string literal: thus, a string literal "Hello" is a const char[6] holding the characters 'H', 'e', 'l', 'l', 'o', and '\0'.

For temporary std::strings it will work as you expected, i.e. no null character contained.

for (char c : std::string{"bar"}) m[c] = 0;

Or

using namespace std::string_literals;
for (char c : "bar"s) m[c] = 0;

BTW as @HolyBlackCat suggested you can also use std::string_view (since C++17) which won't include the null-terminated character when constructed from a c-style string literal. E.g.

for (char c : std::string_view{"bar"}) m[c] = 0;

Or

using namespace std::literals;
for (char c : "bar"sv) m[c] = 0;
like image 72
songyuanyao Avatar answered Mar 11 '26 23:03

songyuanyao



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!