使用 2 个字符串定界符 C++ 选择文本文件的一部分
choose portion of text file using 2 string delimiters c++
我在拆分文本文件时遇到了一点问题;
在我的文本文件中有将近 10000 个像
这样的食谱
-Ing_principal
1 岁
-成分
1 个
ingr 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(); }
但是这个return在无限循环中只有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
的整个输入,因为它不支持在输入中任意移动。使用文件时,这很可能是不必要的。
要执行搜索,最好的解决方案是 std::search
from <algorithm>
,您可以使用它来查找一个序列在另一个序列中的第一次出现。在您的情况下,这是在文件中找到 "-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”)
我在拆分文本文件时遇到了一点问题; 在我的文本文件中有将近 10000 个像
这样的食谱-Ing_principal
1 岁
-成分
1 个
ingr 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(); }
但是这个return在无限循环中只有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
的整个输入,因为它不支持在输入中任意移动。使用文件时,这很可能是不必要的。
要执行搜索,最好的解决方案是 std::search
from <algorithm>
,您可以使用它来查找一个序列在另一个序列中的第一次出现。在您的情况下,这是在文件中找到 "-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”)