在文本文件中搜索某个单词 C++

Posted

技术标签:

【中文标题】在文本文件中搜索某个单词 C++【英文标题】:Searching through a text files for a certain word C++ 【发布时间】:2015-11-30 23:05:42 【问题描述】:

我正在尝试按项目的成分创建一个可搜索的食谱数据库。我正在尝试创建遍历字符串向量(其中保存了每种成分)的 for 循环并搜索文件并比较它们。现在,我只想让它输出“你好!”如果有比赛。经过我所有的摆弄,要么有 100 个 Hello!s(绝对不正确),要么没有。代码如下:

int main()

int y;
cout << "Hello! Welcome to Abby's Recipe Calculator." << endl << endl;
cout << "Please select an option: 1 to search by ingredient or 2 to browse recipes..." << endl;
cin >> y;

vector <string> ingreds;
ingreds.reserve(4); 

if (y == 1)

    ingredientvector(ingreds); // calls function to fill vector w/ ingredients

//else if (y == 2)
//
//call recipe function... 
//

Search x1(ingreds); //assigns ingredients to object vector

recipesearch(x1.getingreds());

system("pause");
return 0;


void ingredientvector(vector<string>& x)
 
cout << "SEARCH BY INGREDIENT" << endl;
cout << "Please enter up to three ingredients... " << endl;

for (int i = 0; i < 4; i++)

    x.push_back("  ");
    getline(cin, x[i]);
    if (x[i] == "1")
    
        break;
    



  

  void recipesearch(const vector<string>& ingredientlist) //ifstream& recipes)
 

ifstream myrecipes;
string line;
string ingredient;
myrecipes.open("recipes.txt");
if (myrecipes.is_open())

    for (int i = 0; i < 4; i++)
    
        ingredient = ingredientlist[i];
        while(getline(myrecipes, line))
            if (ingredient == line)
            
                cout << "Hello!" << endl;
            
            else
            
                break;
            
        
       

else cout << "Unable to open recipe file!";

myrecipes.close();

以下是使用的配方示例:

Cheese-y Ramen

Prep Time: 5 minutes
Cook Time: 20 minutes
Total Time: 25 minutes
Servings: 2
Ingredients:
8 oz cheddar cheese
1 tablespoon cornstarch
¾ cup milk
2 packages ramen noodles
Directions:
1. Grate cheddar cheese and add with cornstarch into a small bowl
2. Combine with milk in a medium saucepan and cook on medium to low heat until consistent. Keep warm until serving.
3. In a separate pan boil ramen noodles. Set aside the included flavor packets.
4. Once boiling, drain the noodles and combine with cheese.
Recipe from Buzzfeed

【问题讨论】:

你能添加一个你的食谱文件的例子吗? i 的一次迭代之后,您处于文件的末尾,并且所有后续迭代将立即中断,因为没有任何内容可供阅读。尝试反转你的循环。 啊,是的。钟华是对的。那会是个问题。 查看上面的内容,您可能需要使用类似于 string::find, cplusplus.com/reference/string/string/find 的内容,除非用户输入“1 汤匙玉米淀粉”。此外,请确保您正在处理在 C++ 中索引从零开始的事实。因此,三个成分只需要:0、1 和 2 即可访问数组中的所有成分。但是你会通过 i 达到 3 多年来我一直在研究食谱数据库系统。我强烈建议使用真实的外部数据库。乱用数据文件是对生产力的浪费。 【参考方案1】:

这会将整个配方文件读入一个字符串,然后在字符串中查找每种成分。注意:这是非常暴力的。它很快,但不会很准确。例如,如果在侧边栏中提及奇多,而不是在食谱本身中,它们仍会被列出。

归功于它的到期,这个答案提升了从Read whole ASCII file into C++ std::string批发读取的文件

void recipesearch(const vector<string>& ingredientlist)


    ifstream myrecipes;
    string file;
    myrecipes.open("recipes.txt");
    if (myrecipes.is_open())
    
        // read entire file into string
        myrecipes.seekg(0, std::ios::end);
        file.reserve(myrecipes.tellg());
        myrecipes.seekg(0, std::ios::beg);

        file.assign((std::istreambuf_iterator<char>(myrecipes)),
                    std::istreambuf_iterator<char>());

        // look inside file string for each ingredient
        for (const string & ingredient: ingredientlist)
        

            if (file.find(ingredient) != file.npos)
             // found ingredient in file
                cout << ingredient << endl;
            
        
    
    else
        cout << "Unable to open recipe file!";


警告:您将从网络上提取的许多文件都以多字节字符集编码以获得更漂亮的结果和国际化,而不是大多数标准 C++ 工具默认使用的 7 位 ASCII,包括上面示例代码中使用的那些。

正确解释可能使用的多个多字节字符集中的哪一个以及如何使用它们本身就是一个讨论主题,但出于此任务的目的,OP 可能能够确保所有输入文件都与ASCII 编码。

【讨论】:

这非常有用! file.reserve(myrecipes.tellg()) 应该是“myrecipes.reverse .....”吗? 我意识到您只是在引用标题“将整个 ASCII 文件读入 C++ std::string”,并且该代码可能确实有效,但问题的数据不是 ASCII。 (推测编码是“系统默认”,所以如果文件保存为“系统默认”并且读取的程序在具有相同默认编码的系统(或用户设置)上运行,它可以工作。)跨度> 非常重要的一点。我是在上面的评论中提出的,真的应该在这里提出来。谢谢@TomBlodget【参考方案2】:

尝试像这样反转 while 和 for 循环:

...the code before your for loop    
while(getline(myrecipes, line))

    for (int i = 0; i < 4; i++)
    
        ingredient = ingredientlist[i];
        if (ingredient == line)
        
            cout << "Hello!" << endl;
        
        else
        
            break;
        
    

...the code after your for loop

【讨论】:

我应该上传文本文件本身吗?它只是一个简单的文本文件,其中包含用破折号列出和潜水的食谱 其实我错了。由于它不是包含,而是完全匹配,因此每次 for 循环迭代只能有一个正确匹配,因此删除了我的额外修改。 嗯,大多数食谱都类似于 3 杯糖。因此,如果您的配料只是说“糖”而不是“3 杯糖”,那么完全匹配就可以了。但是,如果您真的想查看“糖”是否在成分行中,那么您将需要进行包含。 是的,我已经考虑过了,我只是想确保它甚至可以在我使程序更具体之前进行搜索 继续尝试上面发布的代码,看看是否有效。

以上是关于在文本文件中搜索某个单词 C++的主要内容,如果未能解决你的问题,请参考以下文章

简单的二进制搜索对我不起作用。我正在尝试从文本文件中搜索单词

在文件中的某个单词之后附加文本

c++ 文本文件中查找字符串

计算特定单词在 C++ 文本文件中出现的次数

如何在文本文件中搜索单词,如果找到则打印出整行

在 C++ 中将某种结构化的文本文件读入数组