繁体   English   中英

使用2个字符串定界符C选择文本文件的一部分

[英]choose portion of text file using 2 string delimiters c++

我在分割文本文件时遇到了一些问题; 在我的文本文件中,差不多有1万条

-Ing_principal

原料1

-配料

原料1

原料2

原料3

-制备

现在,我如何只获取2个分隔符之间的成分,即成分和准备。

所以我认为这个解决方案

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。 任何人都有好的解决方案或建议?

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

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

您要访问由两个定界符分隔的部分。 那么直接的解决方案是搜索这两个定界符。 然后,您可以复制中间内容以备将来使用。

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

要执行搜索,最好的解决方案是<algorithm> std::search ,您可以使用它来查找另一个序列中第一次出现的序列。 在您的情况下,这是在文件内部找到"-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());

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

我整理了一个小示例 ,尽管您可能希望将读数纳入某个函数中,或者返回相应的文本部分,或者使用函子来处理每个文本部分。


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

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”)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM