【问题标题】:c++ getline reads entire filec ++ getline读取整个文件
【发布时间】:2023-03-04 17:26:01
【问题描述】:

我正在使用 std::getline() 逐行读取文本文件。但是,第一次调用 getline 是读取整个文件!我还尝试将分隔符明确指定为 '\n'。任何想法为什么会发生这种情况?

我的代码:

std::ifstream serialIn;
...
serialIn.open(argv[3]);
...
std::string tmpStr;
std::getline(serialIn, tmpStr, '\n');
// All 570 lines in the file is in tmpStr!
...
std::string serialLine;
std::getline(serialIn, serialLine);
// serialLine == "" here

我使用的是 Visual Studio 2008。文本文件有 570 行(我在 Notepad++ fwiw 中查看它)。

编辑:我通过使用 Notepad++ 将输入文本文件中的行尾转换为“Windows”行尾来解决此问题。该文件是使用 c++ 代码在每行末尾使用 '\n' 编写的。为什么 getline() 需要 Windows 行尾 (\r\n)?这与字符宽度或 Microsoft 实现有关吗?

【问题讨论】:

  • 你能把文件的前10行贴出来吗?
  • 我很确定 getline() 默认使用 '\n' 作为分隔符。我不明白为什么回车会影响它。
  • 标准 I/O 库函数读取和写入平台的行尾。因此,针对 Windows C 或 C++ 运行时构建的程序需要 Windows 行尾(令人震惊!)。
  • 谢谢,jamesdlin。我认为确认这种行为的文档链接比讽刺更有帮助。

标签: c++ file text getline


【解决方案1】:

只是猜测,但是您的文件是否有 Unix 行尾并且您在 Windows 上运行?

【讨论】:

  • +1 只是为了解释一下...在 UNIX/Linux 上,单个换行符(ASCII 代码 10)分隔行,而在 Windows 上则需要回车符 (13) 和换行符。因此,如果您的文件只有换行符,它们可能不会被 C++ 识别为行分隔符,即使某些编辑器会识别它们并向您显示带有预期换行符的文件内容。
  • 我不明白的是,当 getline() 的文档说它单独使用 '\n' (Unix) 行分隔符时,为什么会需要 Windows 行尾 (\r\n) ?此外,我明确将分隔符设置为 '\n' 以确保。您是说文档与实际工作方式之间确实存在差异吗?感谢您的回复。
【解决方案2】:

您将在代码 ('\n') 中看到的 换行符 与平台的实际 行结束表示 混淆了(回车符 ( CR) 和换行 (LF) 字节)。

标准 I/O 库函数会自动将您平台的换行符转换为文本模式流的概念换行符(默认设置)。请参阅 comp.lang.c 常见问题解答中的 What's the difference between text and binary I/O? 。 (虽然这来自 C FAQ,但这些概念也适用于 C++。)由于您在 Windows 上,标准 I/O 函数默认情况下将换行符写入为 CR-LF,并在读取时期望 CR-LF 用于换行符。

如果您不希望完成这些转换并且希望看到原始、纯正的数据,那么您应该将流设置为二进制模式。在二进制模式下,\n 只对应 LF,\r 只对应 CR。

在 C 中,您可以通过将 "b" 作为标志之一传递给 fopen 来指定二进制模式:

FILE* file = fopen(filename, "rb"); // Open a file for reading in binary mode.

在 C++ 中:

 std::ifstream in;
 in.open(filename, std::ios::binary);

或:

 std::ifstream in(filename, std::ios::binary);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-29
    • 2012-10-02
    • 2012-06-17
    • 2017-06-20
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    相关资源
    最近更新 更多