Чтобы продемонстрировать, что произошло, нам нужно проверить различные биты состояния потока.
#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