[英]split a string using multiple delimiters (including delimiters) in 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.