我们如何创建一个循环,这样用户就可以输入一个名字,直到它与C++中包含的任何一个名字匹配

我们如何创建一个循环,这样用户就可以输入一个名字,直到它与C++中包含的任何一个名字匹配,c++,fstream,C++,Fstream,我希望用户输入一个我们已经在文本文件中列出的名称。在用户给出与“itemlist.txt”文件中包含的名称匹配的名称之前,用户必须输入另一个名称,当名称匹配时,循环应中断。我正试着这样做 #include <iostream> #include <fstream> using namespace std; int production, price; string category, item, itemname; int main(){ ifstream

我希望用户输入一个我们已经在文本文件中列出的名称。在用户给出与“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");
   ...
这样,每次通过循环都可以打开并读取文件

while(true){
   ifstream findItem("itemlist.txt");
   ...
不要那样做。效率极低。一个更好的解决方案是读取文件的内容,或者至少将所需的部分读取到可以有效搜索的数据结构中,例如散列集,例如标准库头中的std::unordered_集

然后,您可以从此集合中搜索您的项目

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循环的开头,以倒带流:

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

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;
    }
}

关于你的程序的实际问题是什么?请不要毫无反应,编辑你的问题以便我们能够理解你的问题。实际问题是我的代码并没有按照我想要的那样工作。问题是如何让它工作,如果它在itemlist.txt文件中的循环中断,用户给出一个名称,如果它没有找到,然后重新开始循环,给用户一个输入新名称的机会。你非常理解我,我尝试了你的第一个建议,它工作了。你可以猜到我是C++新手,如果可能的话,我希望你能解释一下你的第二个建议。我对无序的集合项目感到困惑@纳瓦:了解它:-如果在阅读了文档之后,你仍然有关于它的具体问题,在新的帖子中问他们。或者你可以在这里询问它是否与我的答案有关。错误这个文件需要编译器和库支持的ISO C++ 2011标准。此支持目前处于试验阶段,必须使用-std=c++11或-std=gnu++11编译器选项启用。@Nawa:是的,std::无序_集是c++11的一项功能。因此,您需要启用C++11才能使用它。错误消息解释了这一点。如果不能使用C++11,第三方库中有C++98哈希集可用。例如,在。或者您可以简单地用标准头中的std::set替换std::unordered_set。它是基于树的集合,而不是基于哈希映射的集合。它可能会使您的性能稍有下降,但您可能甚至不会注意到其中的差异。通过设置我启用了c++11,它工作正常。学到了新东西。
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;
    }
}