【问题标题】:Wrong behavior with flag ios_base::app标志 ios_base::app 的错误行为
【发布时间】:2012-10-18 01:45:50
【问题描述】:

据我所知,app 标志会在每次写入之前搜索到末尾 const ios_base::openmode std::ios_base::app [static] Seek to end before each write.

以下程序输出为:recostream789

std::string str("t2: 123456789");
std::ostringstream ostr(str,std::ios_base::out|std::ios_base::app);
ostr << "recostream";
std::cout << ostr.str() << std::endl;

不应该输出:t2: 123456789recostream吗?

我正在使用 vs2010

Compiled code image

【问题讨论】:

  • 它按预期对我有用,但使用的是 GCC 4.7。
  • 哦没看到,虽然我是using namespace std,但没有它和std:: 限定符它仍然是相同的输出,还编辑了问题
  • 是的,我看到了更新。我也修改了我的评论。对于这种奇怪的行为似乎没有真正的解释。
  • 在 VS2012 上的行为也相同(不正确)。

标签: c++ sstream


【解决方案1】:

这是开放缺陷LWG #2121,由 Josuttis 今年早些时候打开。他的报告也以 GCC 和 Visual Studio 作为例子,引用:

注意以下程序:

string s("s1: 123456789");
ostringstream s1(s, ios_base::out|ios_base::app);
s1 << "hello";
cout << s1.str() << endl;

使用 g++4.x 打印:

s1: 123456789hello

使用 VisualC++10 打印:

hello23456789

注意,标志 ios_base::ate 的行为在 C++03 中没有明确指定字符串流,但 C++11 added 详细说明了它的字符串流特定效果。它没有为ios_base::app 添加这样的细节,所以一些编译器并没有费心去实现它。

【讨论】:

  • 参考文献+1,缺陷比我读到的更深
【解决方案2】:

是的,我认为它应该 - 至少在我看来,这看起来像是一个编译器(或者,从技术上讲,是库)错误。

快速检查一下,g++ (4.7.1) 似乎同意——它按预期生成t2: 123456789recostream

【讨论】:

  • 注意 this bug report 声称微软是正确的。
  • @JesseGood:我会向 STL 发送一封电子邮件——我没有看到任何内容表明 §27.5.3.1.4/1:app seek to end before each write 应该被忽略。
  • @JerryCoffin:if mode &amp; ios_base::ate is true, pptr() == pbase() + s.size() holds, otherwise pptr() == pbase() is true 怎么样,otherwise pptr() == pbase() 部分似乎说当前位置应该指向开头除非使用ios_base::ate。跨度>
  • @JesseGood:我已经写了另一条评论作为回复,但是看看 Cubbi 的回答,似乎它已经作为一个错误报告给了委员会。我仍然认为 gcc 是对的,而 VC++ 是错的。在指定ios_base::app 的情况下,put 指针应在构造时定位到开头,但在写入前立即定位到结尾。我认为这里没有真正的冲突或缺乏明确性。
  • 是的,直观地说,gcc 是正确的,尽管标准中的当前措辞不够充分(虽然我不明白其中的原因,但 P.J. Plauger 似乎反对它)。
猜你喜欢
  • 1970-01-01
  • 2014-08-21
  • 1970-01-01
  • 1970-01-01
  • 2020-01-27
  • 2011-02-27
  • 2020-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多