c++stdstringnull-terminated

c_str() returns nothing, but string not empty


So, I have a class

class MySuperClass {
public:
 std::string buffer;
};

And wants to print buffer to std::cout. Here's some code about filling string from a file:

MySuperClass msc;
std::fstream file("./favicon.ico", std::fstream::in | std::fstream::binary);
if (file.is_open()) {
 std::stringstream ss;
 while (!file.eof())
   ss << static_cast<uint8_t>(file.get());
 msc.buffer.assign(ss.str());
 file.close();
}

When I output string, all ok. It prints messy, but something. But when I call c_str() on the buffer and try to print, it prints nothing.


Solution

  • An ICO file starts with 2 zero bytes so buffer.c_str() points to an empty string. As a result printing it shows nothing. If you print the byte values you'll immediately see why

    for (const auto c: buffer)
        std::cout << std::setfill('0') << std::setw(2) << std::hex << +c << ' ';
    

    OTOH std::string can contain embedded nulls, printing it outputs the whole file to the output stream

    But why do you print a binary file as text in the first place? It's a very bad idea and may mess up the terminal completely because there may be control characters in the byte stream and you can't ever see normal texts anymore until you reset the terminal. Besides you should read data in big blocks instead which is much faster than operating char-by-char

    See