我们如何创建一个循环,以便用户可以输入一个名称,直到它与使用 C++ 的文本文件中包含的任何一个名称相匹配

How can we create a loop so that user can input a name until it matches any one name included in text file using c++

我希望用户输入我们已经在文本文件中列出的名称。在用户给出的名称与我们的 'itemlist.txt' 文件中包含的名称匹配之前,用户必须输入另一个名称,当名称匹配时,循环应该被中断。我试图这样做....

#include <iostream>
#include <fstream>

using namespace std;

int production, price;
string category, item, itemname;

int main(){

    ifstream findItem("itemlist.txt");
    while(true){
        cout << "item: ";
        cin >> itemname;
        while(findItem >> category >> item >> production >> price){

            if(itemname==item){
                break;
            }
        }

        if(itemname==item){
            break;
        }
        cout << "Item couldn't be found in our data base." << endl;
    }
}

正如您现在所拥有的,您只能通过一次文件。如果输入的第一项不在文件中,则您到达结尾并且无法再阅读。一个非常小的调整将使您的程序工作(尽管非常低效)。只需将 ifstream 创建放在循环中即可。

while(true){
   ifstream findItem("itemlist.txt");
   ...

这样,您每次循环都打开并通读文件。

不要那样做。这是非常低效的。一个更好的解决方案是将文件的内容(或者至少是必要的部分)读取到可以有效搜索的数据结构中,例如哈希集(例如标准库中的 std::unordered_set <unordered_set> header).

std::ifstream findItem("itemlist.txt");
std::unordered_set<std::string> items;
while(findItem >> category >> item >> production >> price)
    items.insert(item);

然后您可以从这个集合中搜索您的项目。

while(true){
    std::cout << "item: ";
    std::cin >> itemname;
    if (items.count(itemname))
        break;
    std::cout << "Item couldn't be found in our data base." << std::endl;
}

每次有人输入无效项目时,您都会浏览整个文件。然后,当输入另一个项目时,文件指针指向末尾。您需要通过将其放在 while (true) 循环的开头来倒回流:

findItem.gseek(0);

不过,就我个人而言,我会编写一次将项目加载到内存中的代码:

struct Item {
    Item(string s) {
        stringstream ss;
        ss << s;
        ss >> category >> item >> production >> price;
    }
    bool operator==(string s) {
        return item == s;
    }
    string category, item;
    int production,  price;
};

int main() {
    ifstream file("itemlist.txt");
    vector<Item> items;
    string cur;
    while (getline(file, cur))
        items.emplace_back(cur);
    string item;
    while (true) {
        cout << "item: ";
        cin >> item;
        std::vector<Item>::iterator it = find(items.begin(), items.end(), item);
        if (it ==  items.end())
            cout << "item not found";
        else break;
    }
}