在rdbuf之后重用stringstream

时间:2014-10-22 20:12:43

标签: c++ stringstream

在将缓冲区推送到具有s函数的另一个流stream后,是否可以重用字符串流.rdbuf()

我重建了情况:

http://ideone.com/JoPJ1E

#include <iostream>
using namespace std;
#include <fstream>
#include <sstream>
#include <assert.h>

ofstream f("t.txt");

void dump(stringstream & s){
    f << s.rdbuf();
    assert(f.good()); // THIS ASSERT FAILS IN my code (see main)
}

void doit1(){

  static std::stringstream s;

  s.str("");
  s.clear();
  s.seekp(0);
  s.seekg(0);

  s << "1";
  dump(s);

}

void doit2(){
  // your code goes here
  std::stringstream s;
  s << "2";
  dump(s);

}

int main() {
    // your code goes here
    doit2();
    doit1(); // ASSERT FAILS HERE
}

我的程序没有崩溃,文本文件中没有输出! 断言通过调用doit1()完全失败,为什么doit2将流f设置为错误状态?

知道这里有什么不对吗?

1 个答案:

答案 0 :(得分:0)

当Dinkumware(微软的STL提供商)在与空内容相关联的流上设置了一个带有搜索引擎优势的0位时,它似乎是long-standing MSVC design issue。显然他们这样做是为了让编译器符合Perennial C++ test suite并且标准规定了这一点。

我发现N3797不太清楚,因为§27.7.3.5basic_ostreamseek members / p3

  

basic_ostream&安培; seekp(pos_type pos);

     

3效果:如果失败()   != true,执行

     
    

rdbuf() - &gt; pubseekpos(pos,ios_base :: out)。的情况下     失败,该函数调用setstate(failbit)(可能会抛出     的ios_base ::失败)。

  
     

4返回:* this。

直接调用pubseekpos(等效)不会触发任何错误。

使用MSVC2013Update4进行测试:

int main() {
    std::stringstream s;
    s.str("");
    if (s.fail())
        cout << "bad"; // not printed
    s.seekp(0);
    // s.rdbuf()->pubseekpos(0, ios_base::out); // Equivalent as per 27.7.3.5/3
    if (s.fail())
        cout << "bad"; // printed
}

Clanggcc工作正常。