Stringstream не передается в строку, к которой добавлен символ конца строки - PullRequest
0 голосов
/ 30 октября 2019

В основном я пытаюсь добавить целые числа в строку, а затем добавить символы строки в строку в определенное время, а затем продолжить добавление целых чисел. Я хочу, чтобы все это было добавлено только к одному строковому объекту.

Поэтому я добавил int в stringstream, передал 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, которые я добавила в поток строк.

Ответы [ 2 ]

6 голосов
/ 30 октября 2019

Чтобы продемонстрировать, что произошло, нам нужно проверить различные биты состояния потока.

#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 success. Fail 0 eof 0 bad 0
2 success. Fail 0 eof 1 bad 0
3 Fail 1 eof 1 bad 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 success. Fail 0 eof 0 bad 0
2 success. Fail 0 eof 1 bad 0
3 success. Fail 0 eof 0 bad 0
4 success. Fail 0 eof 1 bad 0
2
endline

Если мы игнорируем всю информацию о состоянииЯ добавил, что мы действительно получили

2
endline

, а не желаемый

1
2
endline

, потому что 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
endline
3 голосов
/ 30 октября 2019

Используйте stringstream для построения нужного результата, а затем извлеките строку.

ss << 1 << '\n';
ss << 2 << '\n';
h = ss.str();
...