【问题标题】:choose portion of text file using 2 string delimiters c++使用2个字符串分隔符c ++选择文本文件的一部分
【发布时间】:2015-08-08 10:12:01
【问题描述】:

我在拆分文本文件时遇到了一点问题; 在我的文本文件中,有近 10,000 个类似的收件人

-Ing_principal

ingr 1

-成分

ingr 1

ingr 2

ingr 3

-准备

现在我如何才能仅在成分和准备这两个分隔符之间获取成分。

所以我认为这个解决方案

int main() {
string s, t;
bool i = false;
ifstream ricette;
ofstream ingredienti;
ingredienti.open("ingredienti.txt");
ricette.open("ricette.txt", ios::out);
while(ricette) {        
    getline (ricette, s);
    if (s[0] == '-' && s[1] == 'I' && s[5] != 'P') {
        i = true;
        getline(ricette, t);
            while (i) {
                if (t[0] != '-' && t[1] != 'P')
                    cout <<  t << endl;
                else i = false; 

        }
    }
}
ingredienti.close();
ingredienti.close();  }

但这在无限循环中只返回 ingr 1。 谁有好的解决方案或建议?

【问题讨论】:

    标签: c++ string split getline


    【解决方案1】:

    您似乎没有在此循环中读取新的输入行:

            while (i) {
                if (t[0] != '-' && t[1] != 'P')
                    cout <<  t << endl;
                else i = false; 
    
                // Here you'll need to read the next line
            }
    

    这行看起来也很奇怪:

    if (s[0] == '-' && s[1] == 'I' && s[5] != 'P') {
    

    我猜应该是“p”而不是“P”:

    if (s[0] == '-' && s[1] == 'I' && s[5] != 'p') {
    

    顺便说一句 - 你关闭同一个文件两次:

    ingredienti.close();
    ingredienti.close();
    

    但是,我会使用另一种方法来避免两个 while 语句。比如:

    int main() {
        string s;
        bool foundInterestingSection = false;
        ifstream ricette("ricette.txt");
        ofstream ingredienti("ingredienti.txt");
    
        while(getline (ricette, s))
        {
            if (foundInterestingSection)
            {
                if (s == "-Preparation")
                {
                    // The interesting section ends now
                    foundInterestingSection = false;
                }
                else
                {
                    cout <<  s << endl;
    
                    // Write to output file
                    ingredienti << s << endl;
                }
            }
            else
            {
                if (s == "-Ingredients")
                {
                    // The interesting section starts now
                    foundInterestingSection = true;
                }
            }
        }
        ingredienti.close();
        ricette.close();
    }
    

    【讨论】:

      【解决方案2】:

      您想要访问由两个分隔符分隔的部分。然后直接的解决方案是搜索这两个分隔符。然后,您可以复制中间内容以供进一步使用。

      我使用的方法首先缓冲来自std::cin 的整个输入,因为它不支持在输入中任意移动。使用文件时,这很可能没有必要。

      要执行搜索,最好的解决方案是std::search from &lt;algorithm&gt;,您可以使用它在另一个序列中查找第一次出现的序列。在您的情况下,这是在文件中找到 "-Ingredients""-Preparation"

      std::string const start_delimiter{"-Ingredients"};
      auto start = std::search(from, to, start_delimiter.begin(), start_delimiter.end());
      // start now points to '-', assuming the string was found
      std::advance(start, delimiter.size());
      // start now points delimiter.size() characters AFTER the '-', which
      // is the character following the delimiter string
      // ...
      std::string const end_delimiter{"-Preparation"};
      auto end = std::search(start, to, end_delimiter.begin(), end_delimiter.end());
      // Your text is between [start,end)
      from = end;
      std::advance(from, end_delimiter.size());
      

      您可以使用它来查找两个分隔符,然后您可以使用各个迭代器之间的部分来提取/打印/处理您感兴趣的文本。请注意,您可能需要在分隔符中添加换行符根据需要。

      我将 a small example 放在一起,尽管您可能希望将读取分解为某个函数,或者返回相应的文本部分,或者使用函子处理每个文本部分。


      关于您的代码,存在多个问题:

      ifstream ricette;
      // ...
      ricette.open("ricette.txt", ios::out);
      // ...
      getline(ricette, t);
      

      您获取一个输入文件流,打开它以供输出,然后从中读取

        getline(ricette, t);
        while (i) {
                  // ...
        }
      

      您只阅读了一行成分。您需要在循环内执行读取操作,否则 t 将永远不会在 while 循环内更改(这就是您获得无限循环的原因)。

      ingredienti.close();
      ingredienti.close();
      

      ...双关...

      那么,一般来说,你应该直接测试输入操作,即getline

      std::string t; // Use better names, define variables near their use
      while(getline(ricette, t)) {
        if (t[0] == '-' && t[1] == 'P') {
         break;
        }
      }
      // could be eof/failure OR "-P.." found
      

      那么,看到你的测试,想想当你输入一个空行时会发生什么?还是只有一个字符的一行?您还需要测试大小:

      if (t.size() > 1 && t[0] == '-' && t[1] == 'P')
      

      最后,您的代码假定的内容与您告诉我们的内容不同。 (您的分隔符是“-I”,后跟“not p”测试以及“-P”)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多