Search code examples
c++while-looptext-filesifstream

Program never gets to the part where I can input information


When I run the program the output window prints out the line "! Loading Data..." but it seems it's stuck in a loop endlessly. As far as I can tell the while loop is set up correctly, but after plugging away I am at a loss.

ifstream myfile("Data.CS.txt");

if (!myfile) { //Always test the file open. 
    cout << "Error opening output file" << endl;
    system("pause");
    return -1;
}
cout << endl;
cout << "! Loading Data...";
while (getline(myfile, line)) {
    string delimiter = "|";
    string delimiter2 = "-=>";

    size_t pos = 0;
    string tempLine;
    string tokenName;

    string token;
    string token2;

    vector <string> storeTokenPairs;

    tokenName = line.substr(0, pos);
    tempLine = line.erase(0, pos + delimiter.length());

    while ((pos = tempLine.find(delimiter2)) != string::npos) {
        token = tempLine.substr(0, pos);
        storeTokenPairs.push_back(token);
        line.erase(0, pos + delimiter2.length());

    }
    for (int i=0; i<storeTokenPairs.size(); i++)
        dictionary.emplace(tokenName, make_pair(storeTokenPairs[i], storeTokenPairs[i+1]));
}

Solution

  • The following line of code is wrong:

     while ((pos = tempLine.find(delimiter2)) != string::npos) {
        token = tempLine.substr(0, pos);
        storeTokenPairs.push_back(token);
        line.erase(0, pos + delimiter2.length()); // <-- HERE
    }
    

    You are never modifying tempLine, so the loop runs endlessly if delimiter2 is found in tempLine.

    You need to replace line with tempLine instead:

    tempLine.erase(0, pos + delimiter2.length());
    

    Alternatively, you don't actually need to modify tempLine at all, as find() takes an optional start index as input:

    size_t start = 0, pos;
    
    while ((pos = tempLine.find(delimiter2, start)) != string::npos) {
        token = tempLine.substr(start, pos-start);
        storeTokenPairs.push_back(token);
        start = pos + delimiter2.length();
    }
    
    if (start < tempLine.length()) {
        token = tempLine.substr(start);
        storeTokenPairs.push_back(token);
    }