【问题标题】:Is this a bug with cout and getline in g++ 4.7.2?这是 g++ 4.7.2 中 cout 和 getline 的错误吗?
【发布时间】:2012-11-11 23:18:48
【问题描述】:

2012/11/13 更新: 我发现我的问题已经被问到了。 这是处理不同行尾文本文件的一个很好的解决方案: Getting std :: ifstream to handle LF, CR, and CRLF?

是否可以为 libstdc++ 做贡献?怎么样?


2012/11/11

我发现 cout 有问题。
如果 getline() 返回两个字符串,
第二个字符串将覆盖输出中的第一个字符串。

这是示例代码:

#include<iostream>
#include<fstream>
using namespace std;

int main()
{
    //normal code
    cout << "Normal result:" << endl;
    string str1 = "hello";
    cout << str1;
    str1 = "123";
    cout << str1;

    cout << endl;

    //broken code
    cout << "Bug?" << endl;
    ifstream fin;
    fin.open("test.dat");

    string str;

    getline(fin, str);
    cout << str;

    getline(fin, str);
    cout << str;

    fin.close();
    return 0;
}

这里是输入文件(test.dat):

hello
123

输出将是:

Normal result:
hello123
Bug?
123lo

我使用的是 ubuntu 12.10 64 位,
编译器的版本是 g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2.
有什么建议吗? 有没有人告诉我在哪里提交错误?

【问题讨论】:

  • 更新:也许这不是一个错误,而是一个增强。有没有人可以告诉我在哪里提交这个问题?可以在 Bugzilla 上发帖吗?

标签: ubuntu g++ cout getline


【解决方案1】:

比 libstdc++ 中的错误(可能发生,以及 gcc 中的错误,但现在相当少见)更有可能是您的输入文件中的行终止不正确 - 可能是使用 DOS/Windows CR+LF行尾,因为 getline() 丢弃了 LF - 导致第二个字符串覆盖第一个字符串。如果您通过某种十六进制转储程序运行程序的输出,您可以很容易地看到这一点,例如xxd.

在您阅读的字符串末尾检查\r(顺便说一句,MacOS 到版本 9 仅将其用作 EOL 标记),修复您的输入,或在打印时适当地在输出中添加新行。

【讨论】:

  • 我明白了。非常感谢!我忘了我之前为我的文本编辑器 Geany 设置了 CR+LF 模式。我会检查的。
  • 我在 LF 模式下重写了我的输入文件并且代码有效。但我想知道为什么我的文本编辑器可以识别那些不同的行尾,而编译器却不能? :(
  • C++ 使用\n 作为行分隔符,文本编辑器尝试猜测使用什么(对于新文件,他们使用系统默认值,对于现有文件,他们通常检查第一行结尾)。
  • @peterph 我认为是时候打破常规了。有谁知道在哪里提交这个问题?
  • @EriCSN 如果你想抱怨'\n' 是行终止符,我想你必须向C++ 标准化委员会see Wikipedia 投诉。不过,我不确定你会取得多大的成功。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-22
  • 2013-01-22
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
相关资源
最近更新 更多