C++字符串流只获取第一个字符串

C++ Stringstream only picking up first string

本文关键字:字符串 第一个 获取 C++      更新时间:2023-10-16

我有一个文本文件,其中包含一系列两个字符串,每行用冒号分隔。

我使用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,但没有正确重置它。当您从第一行提取第二个单词时,流将耗尽并处于"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异常代码中存在错误,因为人们很少使用它。

我想你正在寻找这样的东西:

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;
}