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

时间:2015-01-03 19:34:26

标签: c++ fstream

我希望用户输入我们已在文本文件中列出的名称。在用户提供与我们的'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;
    }
}

2 个答案:

答案 0 :(得分:0)

如你所知,你只能通过该文件一次。如果输入的第一个项目不在文件中,则到达最后并且无法再读取。一个非常小的调整将使您的程序工作(尽管,非常低效)。只需将ifstream创建放在循环中。

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

这样,每次循环都会打开并读取文件。

不要这样做。这是非常低效的。更好的解决方案是将文件的内容(或至少是必要的部分)读入可以有效搜索的数据结构中,例如哈希集(例如来自标准库的std::unordered_set { {1}}标题)。

<unordered_set>

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

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

答案 1 :(得分:0)

每当有人输入无效项目时,您都会浏览整个文件。然后,当输入另一个项目时,文件指针指向结尾。你需要通过将它放在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;
    }
}