【问题标题】:C++ stringstreams, why getline does not consume content of stream?C ++ stringstream,带有getline不消耗流的内容?
【发布时间】:2020-06-18 16:15:07
【问题描述】:

我发现有关 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()仍然从流中返回完整的字符串。

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

所以我的问题是,如何从字符串流中提取行,并且只有后跟“\n”的行,从以下意义上提取:从字符串流中读取的内容不再在字符串流中,并且还留下不完整的行在流内部保持不变 - 供以后处理。

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

【问题讨论】:

  • en.cppreference.com/w/cpp/string/basic_string/getline 读取关于 delimiter 参数的位。
  • 你的问题的答案:你不能。一旦将某些内容添加到std::stringstream,它就会永久存在,直到std::stringstream 本身被破坏。这是std::stringstream 工作的唯一方式,您无法更改它。
  • 看来你(谢谢)刚刚证实了我个人对这种情况的理解。已经开始实施合适的替代品...

标签: c++ std getline stringstream


【解决方案1】:

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

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

没有一个命令可以从内存中删除你目前已经读过的位;如果您想要该功能,那么stringstream 不是正确使用的类。您可能必须推出自己的 FIFO 结构,例如使用queue&lt;string&gt; 支持流式输入接口。

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

【讨论】:

  • Thx,是的,我刚刚实现了一个基于一个很好的自我管理双链表的新行缓冲区......以及为什么我不能只清除流,在我的程序中,我有时将输出分成几个调用类似于初始字符串、将数组转换为格式良好的表格和结束换行符的函数。或者我在一个循环中打印一个“进度条”,只放一个点。所以我不能保证 linebuffer 在任何随机时间点都只包含完整的行。
猜你喜欢
  • 2013-04-28
  • 2021-04-07
  • 1970-01-01
  • 1970-01-01
  • 2018-03-16
  • 2012-08-04
  • 1970-01-01
  • 2022-06-14
  • 2012-03-15
相关资源
最近更新 更多