【问题标题】:Newline changes how strings read from file are printed in C++换行改变了从文件中读取的字符串在 C++ 中的打印方式
【发布时间】:2019-10-07 09:39:42
【问题描述】:

从 ifstream 读取文本文件以将每一行保存到字符串向量后,应该使用 for 循环打印出来,但它只在 cout 末尾没有换行符时显示最后一行。

我尝试了两种情况来打印字符串向量: 1)cout << s; 2)cout << s << '\n';

其中 s 是迭代每个循环的向量的字符串。 1) 只显示最后一行,而2) 显示整个文本。

ifstream inFile("sample.txt");
string str;
vector<string> strings;

while (getline(inFile, str))
    strings.push_back(str);

for (auto s : strings)
    std::cout << s;

示例文本是:

Test File
The quick brown fox jumps over the lazy dog.

cout &lt;&lt; s; 仅打印:

The quick brown fox jumps over the lazy dog.

cout &lt;&lt; s &lt;&lt; '\n'; 打印:

Test File
The quick brown fox jumps over the lazy dog.

在执行第一个案例时,我期望得到第二个结果。 除了换行符本身,换行符如何改变输出结果?

已编辑: 由于getline() 在到达换行符时停止并且不读取换行符,所以没有\ncout 应该打印Test FileThe quick brown fox jumps over the lazy dog if 程序在 Windows 上执行。因为ifstreamtext 模式下工作,该模式将\r\n 转换为\n

但是,由于我使用的是安装在 cygwin 上的 g++,所以这不太可能发生。这就是Test File\r\nThe quick brown fox jumps over the lazy dog 只显示The quick brown fox jumps over the lazy dog 的原因。

简单地说,\r 使输出行回到原点,并截断了\r 之前的文本。

【问题讨论】:

  • 第一段代码将所有内容打印在一行中。它没有理由跳过任何行。
  • @RSahu 不幸的是,它做到了。我在 Windows 和 Debian 上都试过了。
  • this anwer。您可能面临与该问题的 OP 相同的问题。
  • 如果您在输入文件中翻转行,输出很可能是Test File brown fox jumps over the lazy dog.
  • @RSahu 是的。正确的。我刚刚在 linux 上再次尝试通过创建具有确切文本的确切文件并且它起作用了。我在 linux 上用于测试的文件只是从 Windows 上创建的文件中复制而来的。我认为这是因为 Windows 使用 \r\n 换行,而类 UNIX 系统使用 \n 换行。

标签: c++ cygwin newline cout carriage-return


【解决方案1】:

在 Windows 上,文本文件通常以由回车 (CR) 和换行 (LF) 分隔的行来存储。如果文件以二进制模式打开,则在读取文本时会得到这两个字符。

所以getline,它在'\n'(几乎可以肯定与LF 相同的值)上拆分,为您提供以CR 结尾的行('\r')。

当您打印 CR 时,控制台可能会将光标返回到当前行的开头。然后打印下一行,原来打印的内容被覆盖。由于在您的情况下,第一行比第二行短,因此它看起来就像缺少第一行一样。

这个解释的问题在于

ifstream inFile("sample.txt");

以文本模式打开文件,而不是二进制模式。所以 CR+LF 应该减少到 '\n' 并且它应该工作。

一些可能的解释是:

  1. 您显示的代码与您使用的代码不完全相同,inFile 实际上是以二进制模式打开的。

  2. sample.txt 文件已被损坏,并且包含以 CR+CR+LF 结尾的行。

【讨论】:

  • 我使用十六进制编辑器创建了一个包含Test\rFile 的新文本文件,并且只打印了File。我不使用 IDE,总是使用安装在 cygwin 上的 g++ 编译代码。所以从\r\n\n 的转换可能不会发生,因为它只发生在非unix 系统上。不管怎样,谢谢你让我记住\r是用来返回行首的。
【解决方案2】:

试试cout &lt;&lt; s &lt;&lt; endl;

您可能正在使用设置 iostream 的库、IDE 或调试器,以便仅在新行刷新。

您也可以尝试使用cout &lt;&lt; s &lt;&lt; flush,并注意endl 就像\n 字符加上同花顺。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 2019-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多