【问题标题】:C++: How to iterate over a text in a std::string line by line with STL?C ++:如何使用STL逐行迭代std :: string中的文本?
【发布时间】:2011-05-10 19:50:00
【问题描述】:

我在 std::string 对象中有一个文本。文本由几行组成。我想使用 STL(或 Boost)逐行迭代文本。我提出的所有解决方案似乎都远非优雅。我最好的方法是在换行符处拆分文本。有没有更优雅的解决方案?

更新:这就是我想要的:

std::string input;
// get input ...
std::istringstream stream(input);
std::string line;
while (std::getline(stream, line)) {
  std::cout << line << std::endl;
}

【问题讨论】:

  • 您是否在寻找像 C# 的 foreach “foreach(string line in lines)”这样的“更优雅”?你到底试过什么。如果您习惯于动态或更高级别的语言,C++ 可能会觉得“不优雅”,但在 C++ 中,“优雅”绝不会直接交给您,您通常必须自己编写优雅的程序。
  • 它可能不是相当完全相同的副本,但您可能还想看看:stackoverflow.com/questions/1567082/…
  • 最好回答你自己的问题而不是更新它。更新可能会让未来的读者感到困惑......

标签: c++ string boost stl iterator


【解决方案1】:

为什么将文本保留在源文件中?将其保存在单独的文本文件中。用 std::ifstream 打开它并用 while(getline(...)) 迭代它

#include <iostream>
#include <fstream>

int main()
{
   std::ifstream  fin("MyText.txt");
   std::string    file_line;
   while(std::getline(fin, file_line))
   {
      //current line of text is in file_line, not including the \n 
   }
}

或者,如果文本必须位于 std::string 变量中,则使用 std::istringstream 以类似方式逐行读取

如果您的问题是如何在不使用 + 的情况下将文本按词法方式放入您的代码中,请注意相邻的字符串文字在编译之前会连接起来,因此您可以这样做:

std::string text = 
   "Line 1 contents\n"
   "Line 2 contents\n"
   "Line 3 contents\n";

【讨论】:

  • 如果您确实需要使用std::string,可以将其包装在std::stringstream 中并应用Armen 的解决方案。
  • 如果数据已经是一个字符串,你可以用同样的方式使用std::stringstream
  • @Armen:将从网络上获取文本。当然我可以把它写进一个文件然后再读一遍。我也想出了那个解决方案。我宁愿把它一直记在内存里……如果可能的话:)
  • @Fair:我不明白,真的。您如何阅读网络上的文字?文本是否已经包含换行符?如果是这样,那么我没有看到问题,如果没有,那么也许你想在你认为合适的地方添加它们。另请注意,getline 可以采用第三个参数 - 表示行尾的字符。默认是 '\n' 但你可以改变它
  • @Armen:谢谢指点! std::istringstream 变体是我正在寻找的“优雅”。顺便说一句:我用 libcurl 从网上阅读了文本。
【解决方案2】:

使用Boost.Tokenizer:

std::string text("foo\n\nbar\nbaz");

typedef boost::tokenizer<boost::char_separator<char> > line_tokenizer;
line_tokenizer tok(text, boost::char_separator<char>("\n\r"));

for (line_tokenizer::const_iterator i = tok.begin(), end = tok.end();
     i != end ; ++i)
    std::cout << *i << std::endl;

打印

foo
bar
baz

请注意,它会跳过空行,这可能是也可能不是您想要的。

【讨论】:

  • 不使用 boost::tokenizer 来完成一些可以通过 getline 完成的事情,比如用核武器杀死一只麻雀?
  • 取决于 OP 想要做什么。这个解决方案很短,它产生了一对可以交给 STL 算法的迭代器。
【解决方案3】:

如果你想循环line by line,正如你所说,为什么在换行符处分割文本不是你想要的?

您没有发布代码来展示您的操作方式,但您的方法似乎是正确的,可以完成您所说的您想要的。为什么会觉得自卑?

【讨论】:

  • 我宁愿使用一些 STL 内置解决方案。 AFAIK 行尾取决于平台,所以如果可能的话,我想避免这种解决方案。
  • @Fair:这(连同您当前的代码)似乎应该是原始问题中的信息。这是一个有效的问题,可以解决,但前提是你正面解决它:)
  • @Fair - 我不确定 C++,但 C stdio 函数在阅读时将 \r\n 转换为 \n(除非被告知不要这样做),在写入时将 \n 转换为 \r\n玩得不好的系统。行尾平台依赖性是这里需要担心的小事。
  • 说实话,我还没有真正的工作代码。我想到了一些解决方案 :) 但我稍后会添加一些代码。
猜你喜欢
  • 1970-01-01
  • 2010-12-06
  • 2014-11-08
  • 1970-01-01
  • 2017-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多