我有一个文本文件,其中包含一系列两个字符串,每行用冒号分隔。
我正在使用 getline 获取整行,然后使用字符串流来拆分两个字符串并将它们放到一个 vector 中。该代码在第一次通过时运行良好,它完美地捕获了字符串。然后在 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 获取字符串吗?
最佳答案
您正在重复使用 ss
但没有正确重置它。当您从第一行中提取第二个单词时,流已耗尽并处于“EOF”状态。当流处于这种或任何其他“错误”状态时,它们什么都不做。您必须先清除错误,然后才能继续使用它们。
如果您要检查 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()
member 来设置它,这将替换以前的数据而不是添加到它。
while (std::getline(infile, current_line)) {
ss.clear();
ss.str(current_line);
或者你可以构建一个新的 stringstream
在循环的每次迭代中。这确实确保不会从以前的迭代中遗留任何错误状态或数据。它也可能更慢,但您必须自己分析一下。
while (std::getline(infile, current_line)) {
std::stringstream ss(current_line);
* 异常很好,因为您不需要记住检查它们...除非在默认情况下未启用它们的情况下。我还注意到一些 C++ 实现在他们的 iostreams 异常代码中有错误,因为人们不经常使用它。
关于C++ Stringstream 只获取第一个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41536231/