C++ stringstreams,为什么getline不消耗流的内容?

C++ stringstreams, why getline does not consume content of stream?

我发现关于 stringstreams 和 getline [C++] 的奇怪行为。

我在做什么?

在正常操作中,我将用于登录的字符串填充到字符串流中,我将其用作简单的自缩放缓冲区。然后在某些事件上,我使用 getline 从缓冲流过滤器 em 中提取符合特定条件的完整行,如果它们匹配,我将这些行放入一个或多个输出流以生成日志输出(在屏幕上,到文件,你可以命名。 ..).在程序终止的情况下——正常或异常,我想获取缓冲区中剩余的内容(不完整的行[s])并将其放入输出流。为此,我认为 stringstream 的普通 str() 方法可以完成这项工作。

不幸的是,事实证明 getline 似乎没有使用提取的行,因此 str() 复制了我自程序启动以来的完整日志。哪个

  1. 产生不需要的输出
  2. 必须导致不断增长的日志缓冲区(在给定时间点消耗所有内存)

这个 samal 演示显示了问题:

#include <iostream>
#include <sstream>

using namespace std;

int main(int argc, char **argv)
{
    stringstream ss;

  ss << "1\n1";
  ss << "22\n22";
  ss << "333\n333";
  ss << "4444\n4444";
  ss << "55555\n55555";
  ss << "666666\n666666";
  ss << "7777777\n7777777";

  for (std::string line; std::getline(ss, line); ) {
    cout << line << ",";
  }
  cout << "\n";

  cout << ss.str() << "\n";

    return 0;
}

结果输出为:

1,122,22333,3334444,444455555,55555666666,6666667777777,7777777,
1
122
22333
3334444
444455555
55555666666
6666667777777
7777777
Hit any key to continue...

所以输出的第一行是 getline 提取的内容,之后 std() 仍然是 returns 来自流的完整字符串。

我也有点疑惑,为什么getline也提取最后一个“7777777”,因为它后面没有换行符。

所以我的问题是,如何从字符串流中提取行,并且只提取行后跟 '\n',提取的意义是:从字符串流中读取的内容不再在字符串流中,并且还离开流中未触及的不完整行 - 供以后处理。

PS:我不能使用 boost,它的嵌入式东西和 boost 在这里用得太多了。

首先 getline 可以通过文件结束条件终止,而不仅仅是行终止符。所以这解释了你的最后一行。

关于第一个问题,stringstreams就像一个存储在内存中的文件。从中读取会在不删除文件的情况下推进文件指针。您可以随时倒带回到开头。

没有从内存中删除您目前已阅读的位的命令;如果您想要该功能,那么 stringstream 不适合 class 使用。您可能需要推出自己的 FIFO 结构,例如使用 queue<string> 支持流式输入接口。

或者您可以在完成从中提取所有内容后清除字符串流缓冲区(这似乎是日志缓冲区的正常用法?)