我有一个文本文件,其中包含两行字符串,每行由冒号分隔。
我正在使用getline抓取整行,然后使用字符串流来分割两个字符串并将它们放到矢量上。代码在第一次传递时工作正常,它可以完美地抓取字符串。然后在while循环的第二遍之后,等等,它不会获取新的输入。由于某种原因,字符串流似乎保留了原始的第一个值。
if (infile.is_open()) {
std::stringstream ss;
std::string current_line;
std::string tempProxy;
std::string tempPort;
while (std::getline(infile, current_line)) {
ss << current_line;
std::getline(ss, tempProxy, ':');
std::getline(ss, tempPort);
std::cout << tempProxy << " and " << tempPort << std::endl;
}
知道为什么它不想在第一次迭代之外的任何传递中从current_line中获取字符串?
答案 0 :(得分:4)
您正在重复使用<button align=center>
<canvas width="100" height="25" id="canvas"></canvas>
<span id="submit">Submit</span>
</button>
但未正确重置它。当您从第一行提取第二个单词时,该流已耗尽并处于“EOF”状态。当流处于此状态或任何其他“错误”状态时,它们不执行任何操作。您必须先清除错误,然后才能继续使用它们。
如果您要检查循环中ss
和operator<<
返回的错误(或者如果您导致getline
在错误上抛出异常*),您会发现它们是表示在第一次迭代后它们没有成功。始终检查错误是一种很好的通用做法,尤其是在调试时。
您可以通过更改循环来清除错误:
ss
但是这样做意味着while (std::getline(infile, current_line)) {
ss.clear(); // clears the error, not the contents
ss << current_line;
将累积其内部缓冲区中的所有行。代码将产生您期望的输出,除非文件很大并且您的内存不足或类似的东西。
您可以使用以下内容查看累积的内部缓冲区:
ss
您可能最好使用while (std::getline(infile, current_line)) {
ss.clear();
ss << current_line;
std::cout << "ss internal buffer: " << ss.str();
成员来设置它,而不是使用格式化的输入来添加ss
,这将取代以前的数据,而不是添加到它。
.str()
或者,您可以在循环的每次迭代中构造一个新的while (std::getline(infile, current_line)) {
ss.clear();
ss.str(current_line);
。这确实不会从先前的迭代中携带错误状态或数据。它也可能更慢,但你必须为自己描述一下。
stringstream
*异常很好,因为您不需要记住检查它们......除非在这种情况下默认情况下不启用它们。另外我注意到一些C ++实现在他们的iostreams异常代码中有bug,因为人们不会使用它。
答案 1 :(得分:0)
我认为你正在寻找类似的东西:
if (infile.is_open()) {
std::stringstream ss;
std::string current_line;
std::string tempProxy;
std::string tempPort;
while (std::getline(infile, current_line)) {
std::stringstream to_split;
to_split.str(current_line);
std::getline(to_split, tempProxy, ':');
std::getline(to_split, tempPort);
std::cout << tempProxy << " and " << tempPort << std::endl;
}