簡體   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