std::stringstream 的 seekg 在 while 循环后不起作用
std::stringstream's seekg does not work after while loop
我有这个 std::stringstream
对象,我必须(只)读取它的内容两次。为此,我想我可以使用它的 seekg
成员函数来重复阅读。但我无法让它发挥作用。这是一个重现我遇到的问题的 MWE(改编自示例 in the docs)。
#include <iostream>
#include <string>
#include <sstream>
int main()
{
const char *str = "Hello, world";
std::stringstream ss(str);
std::string word1 = "asdf";
std::string word2 = "qwer";
std::string word3 = "zxcv";
std::string word4 = "yuio";
ss >> word1;
ss.seekg(0); // rewind
ss >> word2;
while (ss >> word3) { }
ss.seekg(0); // rewind
ss >> word4;
std::cout << "word1 = " << word1 << '\n'
<< "word2 = " << word2 << '\n'
<< "word3 = " << word3 << '\n'
<< "word4 = " << word4 << '\n';
}
我希望内容是:
word1 = Hello,
word2 = Hello,
word3 = world
word4 = Hello,
因为 while 循环后的调用 ss.seekg(0)
应该将 ss
放在其内容的开头。为什么我没有得到预期的输出,而是这个?
word1 = Hello,
word2 = Hello,
word3 = world
word4 = yuio
这意味着 word4
永远不会更新,因此语句 ss >> word4
无效。但是在这种情况下,ss.seekg(0)
也没有任何作用。
while 循环是否导致 ss
对象“倒带”失败?也许 ss
试图读取太多,现在处于错误状态(我不知道)。
我该如何解决这个问题?也就是说,我怎样才能使语句 ss >> word4
读作 Hello,
?
我在 C++17 上使用 g++ (Ubuntu 11.1.0-1ubuntu1~20.04) 11.1.0
。
seekg
首先构造并检查哨兵对象(由 cppstreams 使用它来表示任何流故障),如果该哨兵对象表示任何故障,那么函数只是 returns 而不做任何事情。
while 循环后,ss
的failbit
和eofbit
将被设置。对 seekg 的调用将如前所述(不会执行任何操作)。
要使 seekg
生效,您必须在 while 循环之后调用 seekg
本身之前调用 ss.clear()
来清除失败位。然后,哨兵对象不会表示任何失败,seekg
将按预期运行。
相关链接:
https://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt2
我有这个 std::stringstream
对象,我必须(只)读取它的内容两次。为此,我想我可以使用它的 seekg
成员函数来重复阅读。但我无法让它发挥作用。这是一个重现我遇到的问题的 MWE(改编自示例 in the docs)。
#include <iostream>
#include <string>
#include <sstream>
int main()
{
const char *str = "Hello, world";
std::stringstream ss(str);
std::string word1 = "asdf";
std::string word2 = "qwer";
std::string word3 = "zxcv";
std::string word4 = "yuio";
ss >> word1;
ss.seekg(0); // rewind
ss >> word2;
while (ss >> word3) { }
ss.seekg(0); // rewind
ss >> word4;
std::cout << "word1 = " << word1 << '\n'
<< "word2 = " << word2 << '\n'
<< "word3 = " << word3 << '\n'
<< "word4 = " << word4 << '\n';
}
我希望内容是:
word1 = Hello,
word2 = Hello,
word3 = world
word4 = Hello,
因为 while 循环后的调用 ss.seekg(0)
应该将 ss
放在其内容的开头。为什么我没有得到预期的输出,而是这个?
word1 = Hello,
word2 = Hello,
word3 = world
word4 = yuio
这意味着 word4
永远不会更新,因此语句 ss >> word4
无效。但是在这种情况下,ss.seekg(0)
也没有任何作用。
while 循环是否导致 ss
对象“倒带”失败?也许 ss
试图读取太多,现在处于错误状态(我不知道)。
我该如何解决这个问题?也就是说,我怎样才能使语句 ss >> word4
读作 Hello,
?
我在 C++17 上使用 g++ (Ubuntu 11.1.0-1ubuntu1~20.04) 11.1.0
。
seekg
首先构造并检查哨兵对象(由 cppstreams 使用它来表示任何流故障),如果该哨兵对象表示任何故障,那么函数只是 returns 而不做任何事情。
while 循环后,ss
的failbit
和eofbit
将被设置。对 seekg 的调用将如前所述(不会执行任何操作)。
要使 seekg
生效,您必须在 while 循环之后调用 seekg
本身之前调用 ss.clear()
来清除失败位。然后,哨兵对象不会表示任何失败,seekg
将按预期运行。
相关链接:
https://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt2