首页 > 解决方案 > Stringstream 没有输入添加了结束行字符的字符串

问题描述

我基本上是在尝试将整数添加到字符串中,然后在特定时间将结束字符添加到字符串中,然后继续添加整数。我希望将它们全部添加到一个字符串对象中。

所以我在 stringstream 中添加了一个 int,将 stringstream 馈送到一个字符串。然后将 '\n' 添加到字符串中。

然后我将另一个 int 添加到 stringstream,并再次将其提供给字符串。

不幸的是,来自 stringstream 对象的第二个对象没有被添加到字符串中,我不确定它为什么不能。

我尝试将两个对象添加到我的字符串流对象,然后一次将它们提供给字符串一个(中间有结束符),但是 stringstream 一次将字符串中的所有内容添加到字符串中,所以这不起作用.

int main(){
    string h;
    stringstream ss;

    ss << 1;
    ss >> h;
    h += '\n';
    ss << 2;
    ss >> h;
    h += '\n';
    cout << h << "endline";
    cout << endl;

    return 0;
}

当然没有错误消息。我希望它输出:

1
2
endline

相反,我得到

1

endline

所以很明显,字符串添加了我的两个结束行字符,但不是我添加到字符串流中的 2。

标签: c++stringstream

解决方案


为了演示发生了什么,我们需要检查各种流状态位。

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    string h;
    stringstream ss;

    if (ss << 1)
    {
        cout << "1 success. Fail " << ss.fail() 
             << " eof " << ss.eof() << " bad " << ss.bad() << endl;
        if (ss >> h)
        {
            cout << "2 success. Fail " << ss.fail() 
                 << " eof " << ss.eof() << " bad " << ss.bad() << endl;
            h += '\n';
            if (ss << 2)
            {
                cout << "3 success. Fail " << ss.fail() 
                     << " eof " << ss.eof() << " bad " << ss.bad() << endl;
                if (ss >> h)
                {
                    cout << "4 success. Fail " << ss.fail() 
                         << " eof " << ss.eof() << " bad " << ss.bad() << endl;
                    h += '\n';
                    cout << h << "endline";
                    cout << endl;
                }
                else
                {
                    cout << "4 Fail " << ss.fail() << " eof " << ss.eof() 
                         << " bad " << ss.bad() << endl;
                }
            }
            else
            {
                cout << "3 Fail " << ss.fail() << " eof " << ss.eof() 
                     << " bad " << ss.bad() << endl;
            }
        }
        else
        {
            cout << "2 Fail " << ss.fail() << " eof " << ss.eof() 
                 << " bad " << ss.bad() << endl;
        }
    }
    else
    {
        cout << "1 Fail " << ss.fail() << " eof " << ss.eof() 
             << " bad " << ss.bad() << endl;
    }
    return 0;
}

输出

1成功。失败 0 eof 0 坏 0
2成功。失败 0 eof 1 坏 0
3 失败 1 eof 1 坏 0

所以第一次写入成功。无懈可击的胜利。但是第一次读取读取流中的所有内容并到达文件末尾(不是流是文件,而是名称卡住了),设置了 EOF 位。一旦设置了 EOF 位,除了清除该位并祈祷有人添加更多要读取的数据之外,您对流无能为力。

更多数据被添加到流中,但由于 EOF 位,文件无法接受它。

如果我们清除 EOF

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    string h;
    stringstream ss;

    if (ss << 1)
    {
        cout << "1 success. Fail " << ss.fail() << " eof " << ss.eof() 
             << " bad " << ss.bad() << endl;
        if (ss >> h)
        {
            cout << "2 success. Fail " << ss.fail() << " eof " << ss.eof() 
                 << " bad " << ss.bad() << endl;
            h += '\n';
            ss.clear(); // added this
            if (ss << 2)
            {
                cout << "3 success. Fail " << ss.fail() << " eof " << ss.eof() 
                     << " bad " << ss.bad() << endl;
                if (ss >> h)
                {
                    cout << "4 success. Fail " << ss.fail() << " eof " << ss.eof() 
                         << " bad " << ss.bad() << endl;
                    h += '\n';
                    cout << h << "endline";
                    cout << endl;
                }
                else
                {
                    cout << "4 Fail " << ss.fail() << " eof " << ss.eof() 
                         << " bad " << ss.bad() << endl;
                }
            }
            else
            {
                cout << "3 Fail " << ss.fail() << " eof " << ss.eof() 
                     << " bad " << ss.bad() << endl;
            }
        }
        else
        {
            cout << "2 Fail " << ss.fail() << " eof " << ss.eof() 
                 << " bad " << ss.bad() << endl;
        }
    }
    else
    {
        cout << "1 Fail " << ss.fail() << " eof " << ss.eof() 
             << " bad " << ss.bad() << endl;
    }
    return 0;
}

现在的输出是

1成功。失败 0 eof 0 坏 0
2成功。失败 0 eof 1 坏 0
3成功。失败 0 eof 0 坏 0
4成功。失败 0 eof 1 坏 0
2
端线

如果我们忽略我添加的所有状态信息,我们真的得到了

2
端线

不是想要的

1
2
端线

因为ss >> h会覆盖h. “1\n”被“2”抹去

获得所需内容的最简单方法是将所有内容写入其中,然后将内容作为string.

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    string h;
    stringstream ss;

    if (ss << 1 << '\n' << 2 << '\n')
    {
        cout << ss.str() << "endline";
        cout << endl;
    }
    else
    {
        cout << "Fail " << ss.fail() << " eof " << ss.eof()
             << " bad " << ss.bad() << endl;
    }
    return 0;
}

这次的输出是

1
2
端线

推荐阅读