简体   繁体   English

在rdbuf之后重用stringstream

[英]reuse stringstream after rdbuf

Is it possible to reuse a stringstream s after pushing the buffer to another stream stream with the .rdbuf() function? 是否有可能重新使用字符串流s推缓冲区到另一个流后stream.rdbuf()函数?

I reconstructed the circumstances: 我重构了情况:

http://ideone.com/JoPJ1E 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
}

My program does not crash, and there is no output in the text file! 我的程序不会崩溃,并且文本文件中没有输出! The assert fails exactly by calling doit1(), why does doit2 set the stream f in a bad state?? 断言通过调用doit1()完全失败,为什么doit2将流f设置为错误状态?

Any idea what could be wrong here? 知道这里有什么问题吗?

It seems a long-standing MSVC design issue by Dinkumware (the STL-provider for Microsoft) when setting a 0-position with seekp on a stream associated with an empty content. Dinkumware(Microsoft的STL提供者)在将与空内容相关联的流上的带有seekp的位置设置为0时,似乎是一个长期存在的MSVC设计问题 Apparently they did this to have the compiler conform to the Perennial C++ test suite and that the standard dictated that. 显然,他们这样做是为了使编译器符合Perennial C ++测试套件 ,并且该标准对此进行了规定。

I find this not very clear with N3797 since §27.7.3.5 basic_ostream seek members/p3 says 我发现N3797不太清楚,因为§27.7.3.5basic_ostream seek成员/ p3

basic_ostream& seekp(pos_type pos); basic_ostream&seekp(pos_type pos);

3 Effects: If fail() != true, executes 3个效果:如果fail()!= true,则执行

rdbuf()->pubseekpos(pos, ios_base::out) . rdbuf()-> pubseekpos(pos,ios_base :: out) In case of failure, the function calls setstate(failbit) (which may throw ios_base::failure). 如果发生故障,该函数将调用setstate(failbit)(可能会引发ios_base :: failure)。

4 Returns: *this. 4返回:* this。

And calling pubseekpos (equivalent) directly doesn't trigger any bug. 直接调用pubseekpos (等效)不会触发任何错误。

Tested with MSVC2013Update4: 使用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
}

Clang and gcc work just fine. Clanggcc可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM