2

我正在使用 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 实现有关?

4

2 回答 2

6

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

于 2012-08-28T03:16:18.517 回答
3

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

标准 I/O 库函数自动将平台的行尾转换为文本模式流的概念换行符(默认值)。请参阅文本和二进制 I/O 有什么区别?来自 comp.lang.c 常见问题解答。(尽管这来自 C FAQ,但这些概念也适用于 C++。)由于您使用的是 Windows,标准 I/O 函数默认情况下将换行符写入为 CR-LF,并在读取时期望 CR-LF 用于换行符。

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

"b"在 C 中,您可以通过将其作为标志之一传递给来指定二进制模式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);
于 2012-08-29T10:45:03.113 回答