C++ Stringstream 只拾取第一个字符串
Posted
技术标签:
【中文标题】C++ Stringstream 只拾取第一个字符串【英文标题】:C++ Stringstream only picking up first string 【发布时间】:2017-05-23 00:26:26 【问题描述】:我有一个文本文件,其中包含一系列两个字符串,每行用冒号分隔。
我使用 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 中获取字符串吗?
【问题讨论】:
为什么ss
,tempProxy
和tempPort
在外部范围内?为什么ss
不是std::istringstream
简单地从current_line
构造?
这很奇怪,我认为在循环外构造一次字符串流并使用 >> 运算符为其提供一个新流将比每次通过循环构造它更有效。
【参考方案1】:
您正在重复使用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()
成员来设置它,这将替换以前的数据而不是添加到它。
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 异常代码中存在错误,因为人们不经常使用它。
【讨论】:
【参考方案2】:我认为您正在寻找类似的东西:
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;
【讨论】:
这很奇怪,我认为在循环外构造一次字符串流并使用 >> 运算符为其提供一个新流将比每次通过循环构造它更有效。但它似乎只对你有用,而不是我的。以上是关于C++ Stringstream 只拾取第一个字符串的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 中使用 stringstream 获取字符串中的所有 N 个连续字符