【问题标题】:C++ streams can't tell where one string ends and the next begins?C++ 流无法分辨一个字符串在哪里结束,下一个从哪里开始?
【发布时间】:2023-08-31 22:01:01
【问题描述】:

我正在向 ofstream 写入一个字符串和一个 int,然后尝试使用 ifstream 将其读回。我希望字符串以空值结尾,因此流应该知道字符串在哪里停止以及 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 
}

我怎样才能将字符串和 int 分开,而不是将它们组合成一个字符串?

【问题讨论】:

  • 流中没有字符串或整数。如果你想区分事物,你需要设计并使用一种格式来做到这一点。逗号分隔值和 XML 是两种方法。还有其他的。
  • 流不是协议,它只是一个可以向下发送字节的管道。
  • 但是内存中的字符串有一个空终止符。该流不会保存那个空终止符吗?
  • 一个 std::string 可能包含嵌入的空值。这些空值将被输出。最终的空终止符是实现的一部分,但不是字符串数据的一部分,不会被输出。您需要使用某种方法来分隔流中的字段。有很多方法可以解决这个问题。

标签: c++ stream ifstream ofstream


【解决方案1】:

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

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

但为什么需要换行符?字符串以空值结尾,所以 c++ 不应该将该空字符写入字节流吗?如果是这样的话, 那为什么需要换行呢?

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

std::string 不一定要以 nul 结尾。它有 size 并且应该被视为字符数组/向量。如果 str 构造为,您可以将 nul 写入流:

std::string outStr1{'H', 'e', 'l', 'l', 'o', 0};

同时

 std::string s("OK");

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

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

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

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

【讨论】:

  • 战术说明:'\n' 比 std::endl 便宜得多,因为 std::endl 内置了流刷新。
  • 但是为什么需要换行符呢?该字符串是以空字符结尾的,所以 c++ 不应该将该空字符写入字节流吗?如果是这样,那为什么需要换行符?
最近更新 更多