Can somebody please explain this? Is it a bug??

So my code is working fine except when I go to enter the second.title it just skips the prompt as if the cin isn't even present and outputs the second.genre prompt. Then if I take out the second.title prompt, it starts treating the second.genre prompt as if the cin isn't present.

Can somebody explain if it's something with the struct or just getline???

Much appreciated

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  #include <iostream>
#include <string>
#include <climits>

using namespace std;


struct MovieData
{
    string title;
    string genre;
    string director;
    int year;
    int runtime;
};

void displayMovie(MovieData first, MovieData second);

int main()
{
    MovieData first;
    MovieData second;
    
    cout << "Entering data for movie #1" << endl;
    cout << "Enter the title of the movie: ";
    getline(cin, first.title);
    cout << "Enter the genre of the movie: ";
    getline(cin, first.genre);
    cout << "Enter the director's name: ";
    getline(cin, first.director);
    cout << "Enter the year the movie was released: ";
    cin >> first.year;
    while(!cin || first.year <= 1887)
    {
        cout << "The year should be a number after 1887." << endl;
        cin.clear();
        cin.ignore(INT_MAX, '\n');
	        
        cout << "Enter the year the movie was released: ";
	    cin >> first.year;
    }
    cout << "Enter the runtime in minutes: ";
    cin >> first.runtime;
    while(!cin || first.runtime <= 0)
    {
        cout << "The runtime should be a number greater than 0." << endl;
        cin.clear();
        cin.ignore(INT_MAX, '\n');
        	        
        cout << "Enter the runtime in minutes: ";
        cin >> first.runtime;
    }
    cout << endl;
    
    cout << "Entering data for movie #2" << endl;
    cout << "Enter the title of the movie: ";
    getline(cin, second.title);
    cout << "Enter the genre of the movie: ";
    getline(cin, second.genre);
    cout << "Enter the director's name: ";
    getline(cin, second.director);
    cout << "Enter the year the movie was released: ";
    cin >> second.year;
    while(!cin || second.year <= 1887)
    {
        cout << "The year should be a number after 1887." << endl;
        cin.clear();
        cin.ignore(INT_MAX, '\n');
	        
        cout << "Enter the year the movie was released: ";
	    cin >> second.year;
    }
    cout << "Enter the runtime in minutes: ";
    cin >> second.runtime;
    while(!cin || second.runtime <= 0)
    {
        cout << "The runtime should be a number greater than 0." << endl;
        cin.clear();
        cin.ignore(INT_MAX, '\n');
        	        
        cout << "Enter the runtime in minutes: ";
        cin >> second.runtime;
    }
    cout << endl;
    
    displayMovie(first, second);
    
    
    return 0;
}
Without even looking at your program, I am already 90% it is getline().

Yup.

Lines 26-30: getline()
Line 32: cin
Line 43: cin
Line 57: getline()

Mixing unformatted with formatted input. Very, very common error for inexperienced programmers (no offense).

Having multiple cin's before a getline is what causes the problem, because it leaves an extra '\n' in the buffer. So when it comes to getline(), it reads in the '\n' and skips over without the user having entered anything.

What you need to do is, wherever that happens, stick a cin.ignore ('\n'); right before the getline(). That will ignore the extra newline in the buffer and allow you to enter stuff normally.

That's what I do, anyway, and it works!

Check out this post: https://www.cplusplus.com/forum/beginner/1988/4/#msg17198
It has a lot of good info about formatted and unformatted input.
Hello domweng,

I see that you have your answer. Here are some suggestions that might help.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <iostream>
#include <limits>     // <--- Should be using this 1.
#include <string>
//#include <climits>  // <--- This 1 not needed.

using namespace std;  // <--- Best not to use.

struct MovieData
{
    string title;
    string genre;
    string director;
    int year{};  // <--- The "cin" ALWAYS initialize all your variables.
    int runtime{};
};

//void displayMovie(MovieData first, MovieData second);

int main()
{
    MovieData first;
    MovieData second;

    cout << "Entering data for movie #1\n\n";

    cout << "Enter the title of the movie: ";
    getline(cin, first.title);
    
    cout << "Enter the genre of the movie: ";
    getline(cin, first.genre);
    
    cout << "Enter the director's name: ";
    getline(cin, first.director);

    //cout << "Enter the year the movie was released: ";
    //cin >> first.year;

    while (cout << "Enter the year the movie was released: " && !(cin >> first.year) || first.year <= 1887)
    {
        if (!std::cin)
        {
            cout << "\n     Invalid Input! Must be a number.\n\n";
            cin.clear();
            //cin.ignore(INT_MAX, '\n');
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
        }
        else if (first.year <= 1887)
        {
            cout << "\n     The year should be a number after 1887.\n\n";
        }
    }

    cout << "Enter the runtime in minutes: ";
    cin >> first.runtime;

    while (!cin || first.runtime <= 0)
    {
        cout << "The runtime should be a number greater than 0.\n";
        cin.clear();
        cin.ignore(INT_MAX, '\n');

        cout << "Enter the runtime in minutes: ";
        cin >> first.runtime;
    }

    cout << '\n';

    cout << "Entering data for movie #2\n";

    cout << "Enter the title of the movie: ";
    getline(cin, second.title);
    
    cout << "Enter the genre of the movie: ";
    getline(cin, second.genre);
    
    cout << "Enter the director's name: ";
    getline(cin, second.director);

    cout << "Enter the year the movie was released: ";
    cin >> second.year;

    while (!cin || second.year <= 1887)
    {
        cout << "The year should be a number after 1887." << endl;
        cin.clear();
        cin.ignore(INT_MAX, '\n');

        cout << "Enter the year the movie was released: ";
        cin >> second.year;
    }

    cout << "Enter the runtime in minutes: ";
    cin >> second.runtime;

    while (cout << " Enter the runtime in minutes: " && !(cin >> second.runtime) || second.runtime <= 0)
    {
        if (!std::cin)
        {
            cout << "\n     Invalid Input! Must be a number.\n\n";
            cin.clear();
            cin.ignore(INT_MAX, '\n');
        }
        else if (second.runtime <= 0)
        {
            cout << "\n     The runtime should be a number greater than 0.\n";;
            cin >> second.runtime;
        }
    }

    cout << '\n';

    //displayMovie(first, second);

    return 0;
}

Be sure to read the comments in the code.

Lines 38 - 51 Tend to work better for numeric input. See the programs output later.

Prefer to use the new line, (\n), over the function "endl".

I do not know what compiler or header files you are using, but "INT_MAX" may not be big enough to cover the buffer used for input or it may be to small. In my VS 2017 for the line std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');. "std::streamsize" is defined as a "long long". A much larger number than "INT_MAX". Also is has been called the most portable way to use this as any compiler and header files will return the maximum size of the buffer.

The other alternative is to ignore 1000 or 10000 and this size is usually enough.

I did not change all the while loops. somehow I did the last 1 first and the 1st last.

I left lines 35 and 36 so that you could compare them with line 38.

The initial run I get is:

Entering data for movie #1

Enter the title of the movie: Mivie 1
Enter the genre of the movie: Comedy
Enter the director's name: Mel Brooks

Enter the year the movie was released: a

     Invalid Input! Must be a number.

Enter the year the movie was released: 1776

     The year should be a number after 1887.

Enter the year the movie was released: 1977
Enter the runtime in minutes: 100

Entering data for movie #2

Enter the title of the movie: Enter the genre of the movie:



Andy

Edit:

P.S. Notice the use of the blank lines to make the code easier to read.
Last edited on
Topic archived. No new replies allowed.