0

So I have been studying programming from the book PPP by Bjarne Stroustrup and there is the following assignment:

  1. Write a program where you first enter a set of name·and·value pairs, such as Joe 17 and Barbara 22. For each pair, add the name to a vector called names and the number to a vector called scores (in corresponding positions, so that if names[7]=="Joe" then scores[7]==18). Terminate input by the line No more ("more" will make the attempt to read another integer fail ). Check that each name is unique and terminate with an error message if a name is entered twice. Write out all the (name,score) pairs, one per line.
  2. Modify the program from exercise 19 so that when you enter a name, the program will output the corresponding score or "name not found".
  3. Modify the program from exercise 19 so that when you enter an integer, the program will Output all the names with that score or "score not found". So this is the code I wrote:

    using namespace std;
    
    int main() {
        vector <string> names;
        string name;
        vector <int> scores;
        int score;
        string finish = "no more";
        cout << "Please write a player's name and the player's score: \n";
        while (name != "|") {
            cin >> name;
            cin >> score;
            names.push_back(name);
            scores.push_back(score);
            cin.ignore();
        }       
        for (size_t j = 0; j < scores.size(); j++) {
        for (size_t p = 0; p < scores.size(); p++) {
            if (names[j] == names[p] && j != p) {
                cout << "Error! You have reiterated the name: " << names[j] << "\n";
                system("pause");
                return 1;
                }
            }
        }
        cout << "Please insert a name to see it's score:\n";
        string s = " ";
        cin >> s;
            for (size_t d = 0; d < scores.size(); d++) {
                if (s == names[d]) { 
                    cout << names[d] << "'s score is: " << scores[d] << "\n";
                }
        }
        system("pause");
    }
    

Now my problem is quite simple I believe. In the second cin (cin >> s) the compiler simply seems to skip this line and terminates the program instead of letting me write an input. I read online that it is because that you can't use cin twice so when I added the line cin.ignore(), hoping that the problem will be solved, it did not help solve the problem. Any tips on how to fix this?

Loay Ashmawy
  • 637
  • 1
  • 7
  • 24
C.H.
  • 23
  • 8
  • 1
    It's not the compiler ignoring the line, but the program. The title is thus misleading. – riodoro1 Mar 15 '17 at 15:31
  • @riodoro1 Noted and fixed :) – C.H. Mar 15 '17 at 15:33
  • Do your names have spaces in them? – NathanOliver Mar 15 '17 at 15:34
  • 1
    It's not skipping the line. Try putting `cout << s << '\n';` after it to see what it read. – Barmar Mar 15 '17 at 15:34
  • @Barmar It simply skips it and it won't let me enter any input when it really should.. – C.H. Mar 15 '17 at 15:35
  • I don't think so. I think it's reading the input that it got an error from when you tried to do `cin >> score;` and entered something that wasn't a number. – Barmar Mar 15 '17 at 15:36
  • Most likely this is a dupe of [this](http://stackoverflow.com/questions/5838711/stdcin-in-input-with-spaces)(read string with spaces) and [this](http://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction)(mixing getline and cin) – NathanOliver Mar 15 '17 at 15:39

2 Answers2

2

I think the problem is that when you use cin >> score and enter something that isn't an integer, the error flag on the cin stream is set, and future operations fail. You need to clear this error with cin.clear() before you read more input.

Your loop for the student names is also wrong. You never check for the "no more" name. You check for "|" as the name, but not until you finish processing the input. As the instructions say, the purpose of using no more as the input is so that cin >> score will fail because more is not a number.

Instead, use while (cin >> name >> score) to read both the name and score at once. When you enter an invalid score, this will fail and the loop ends.

using namespace std;

int main() {
    vector <string> names;
    string name;
    vector <int> scores;
    int score;
    cout << "Please write a player's name and the player's score: \n";
    while (cin >> name >> score) {
        names.push_back(name);
        scores.push_back(score);
        cin.ignore();
    }       
    cin.clear(); // Clear error flag from above
    for (size_t j = 0; j < scores.size(); j++) {
        for (size_t p = 0; p < scores.size(); p++) {
            if (names[j] == names[p] && j != p) {
                cout << "Error! You have reiterated the name: " << names[j] << "\n";
                system("pause");
                return 1;
            }
        }
    }
    cout << "Please insert a name to see it's score:\n";
    cin >> s;
    for (size_t d = 0; d < scores.size(); d++) {
        if (s == names[d]) { 
            cout << names[d] << "'s score is: " << scores[d] << "\n";
        }
    }
    system("pause");
}
Barmar
  • 596,455
  • 48
  • 393
  • 495
-1

What happens here is, when you press enter the character '\n' is still in the stream. So you need to flush cin to be able to continue again. To do so use

std::cin.clear();
std::cin.ignore(numeric_limits<streamsize>::max(), '\n');

after every call to cin. The numeric_limits<streamsize>::max can be use with the header #include <limits>

DatCorno
  • 81
  • 1
  • 9
  • `operator >>` ingnores white space which `\n` is considered to be. – NathanOliver Mar 15 '17 at 15:40
  • Thanks, I did not know that. Why is the code working with the snippet I provided then? – DatCorno Mar 15 '17 at 15:43
  • Well now after adding these lines it simply won't execute anything when I tell it to. It simply does "\n" instead of executing the code. – C.H. Mar 15 '17 at 15:44
  • Aren't the default arguments to `cin.ignore()` the same as the ones you gaver? – Barmar Mar 15 '17 at 15:45
  • The most likely problem is one of the names has a space in it. That will cause `cin >> score` to fail since there will still be text in the buffer. That in turn means ever other call to `cin` will fail untill the buffer and error flags are cleared. – NathanOliver Mar 15 '17 at 15:46
  • @Barmar `ignore` is `ignore( std::streamsize count = 1, int_type delim = Traits::eof() )` – NathanOliver Mar 15 '17 at 15:46
  • @ChenHaviv the code works fine on my end. Did you had the `cin.clear()` and `cin.ignore()` directly after the `cin >> name`? – DatCorno Mar 15 '17 at 15:49