C++ 流无法判断一个字符串在哪里结束,下一个字符串从哪里开始?

C++ streams can't tell where one string ends and the next begins?

我正在将一个字符串和一个 int 写入一个 ofstream,然后尝试用一个 ifstream 读回它。我希望字符串以 null 终止,因此流应该知道字符串在哪里停止以及 int 在哪里开始。但这并没有发生——当我读回它时,它将 int 视为字符串的一部分。我该如何避免这种情况?

#include <fstream>
#include <string>

int main()
{
    std::string tempFile("tempfile.out");
    std::ofstream outStream(tempFile); //Tried this both with text 
    //and with ::bin but get same results

    std::string outStr1("Hello");
    int outInt1 = 5;
    std::string outStr2("Goodbye");

    outStream << outStr1 << outInt1 << outStr2;
    outStream.close();

    std::ifstream inStream(tempFile);  //Tried this both with text 
    //and with ::bin but get same results
    std::string inStr1, inStr2;
    int inInt1;
    inStream >> inStr1; //this reads a string that concats all 
    //my prev values together!
    inStream >> inInt1; //doesn't do what I want since the int was 
    //already read as part of the string
    inStream >> inStr2; //doesn't do what I want 
}

如何将字符串和整数分开,而不是将它们组合成一个字符串?

您可以简单地添加换行符来分隔字符串

outStream << outStr1 << std::endl << outInt1 << std::endl << outStr2;

But why is the newline needed? The string is null-terminated, so shouldn't c++ write that null character to the byte stream? If so, then why is a newline needed?

它不一定是换行符,尽管换行符对你有用...

std::string 不一定非要以 nul 结尾。它有 size 并且应该被视为 array/vector 个字符。如果 str 构造为:

,则可以将 nul 写入流
std::string outStr1{'H', 'e', 'l', 'l', 'o', 0};

 std::string s("OK");

构造一个大小为 2 的字符串。

当您从流中读取数据时,它需要知道规则 来提取字节并转换为预期的类型。基本上,如果您从流中读取一个字符串,它需要知道何时结束该字符串。简单的规则是,如果它达到 space(std::isspace()),则字符串终止。这里space表示白色space、tab、换行等

比如说,如果你想提取一个整数,它应该在到达一个整数符号中不合法的字符时停止,比如 'z'。

要完全理解这一点,http://en.cppreference.com/w/cpp/concept/FormattedInputFunction 是一个好的开始。