简体   繁体   中英

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++

I want user to input a name that we already had listed in text file. Until a user give a name that matches with a name which contain in our 'itemlist.txt' file user have to input another name and when a name matches the loop should be break. I was trying to do like this....

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

As you have it now, you only get one pass through the file. If the first item entered is not in the file, you reach the end and cannot read any more. A very minor tweak will make your program work (albeit, very inefficiently). Just put the ifstream creation inside the loop.

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

That way, you are opening and reading through the file each time through the loop.

Don't do that. It is extremely inefficient. A much better solution is to read the contents of the file (or at least, the parts that are necessary) into a data structure which can be searched efficiently, such as a hash set (eg std::unordered_set from the standard library <unordered_set> header).

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

Then you can search for your item from this set.

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

Every time someone enters an invalid item, you go through the entire file. Then, when another item gets entered, the file pointers points the the end. You need to rewind the stream by putting this at the beginning of the while (true) loop:

findItem.gseek(0);

Personally, however, I would write the code to load the items into memory once:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM