getline error

I've been fiddling with the cin and getline functions lately, but I haven't wrapped my head on why this piece of code doesn't work. I combined my code starting from another tutorial I've done just recently, but for some reason if I were to use the getline function for what I'm trying to do below, it would just skip to the next cout function instead of telling me to input something. Here is the code:

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
#include <iostream>
#include <string>
using namespace std;

int main ()
{
    int number1;
    int a;
    int b;
    string mystr;

    cout << "Hi." << endl;
    cout <<"Please enter an integer value." <<endl;
    cin >> number1;
    cout << "The number you have put in is "<< number1 << "." <<endl;
    cout << "The number doubled is " << number1*2<< "." <<endl; 
    cout << "The number subtracted by 3 is " <<number1-3<<"."<<endl;
    cout << "The number added by 5 is " <<number1+5<<"."<<endl;
    cout << "Now, enter two more numbers."<<endl;
    cin >> a >> b;
    cout << "This is the number of the two added together: " << a+b <<endl;
    cout << "Ok, now tell me your name."<<endl;
    getline (cin, mystr);
    cout << "I'll place it here again: " << mystr<<endl;
    system("PAUSE");
    return 0;
}


Once all the integers are input, the last cout functions that ask for the name go through without letting me input my string. However, after messing around with the sample coding I realized something: Placing a getline function with a string doesn't work, but if another getline function were to be placed again, then the code will function as should be. This is the final code with the solution:

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
#include <iostream>
#include <string>
using namespace std;

int main ()
{
    int number1;
    int a;
    int b;
    string mystr;
    
    cout << "Hi." << endl;
    cout <<"Please enter an integer value." <<endl;
    cin >> number1;
    cout << "The number you have put in is "<< number1 << "." <<endl;
    cout << "The number doubled is " << number1*2<< "." <<endl; 
    cout << "The number subtracted by 3 is " <<number1-3<<"."<<endl;
    cout << "The number added by 5 is " <<number1+5<<"."<<endl;
    cout << "Now, enter two more numbers."<<endl;
    cin >> a >> b;
    cout << "This is the number of the two added together: " << a+b <<endl;
    cout << "Let's try this now."<<endl;
    getline (cin, mystr);
    cout << "Tell me your name." << mystr <<endl;
    getline (cin, mystr1);
    cout << "I'll place it here again: " << mystr<<endl;
    cout << "And...1+1 = ?" <<endl;
    getline (cin, mystr);
    cout << mystr<<"? Well I'm not programmed to figure out if that's right or not."<<endl;
    system("PAUSE");
    return 0;
}


Now I did solve my problem. But I know that there's a better way of doing this. Can anyone tell me what I did wrong with my initial code and why the getline function doesn't work? This only fails whenever I have to input integers though. Whenever I put the string input section to the top of the code, it would work just fine.
When you input an integer, or other value using the extraction operator >>, the input process stops at the first whitespace or non-numeric character. Any unprocessed characters remain in the input buffer. That includes the newline character '\n' which was entered from the keyboard after the data.

If you then do a getline() operation, it will process everything up to the first newline character. The newline itself is discarded. Hence it will get the remnants of the previous input, which is an empty line.

You could either do the getline and ignore the result, or use the cin.ignore() function with a delimiter of '\n'.
Yeah you have to clear the buffer before using the getline or cin since the search for the newline and whitespace characters respectively by default.

So something like:

1
2
3
cin.ignore();   //clear the buffer
cout<<"How are you?"<<endl;
getline(cin,x);


HTH,
Aceix
That fixed the issue. Chervil, I still don't quite understand the idea behind the process of the buffer...Do you mean that the getline process takes the newline and jumps to the next cout function?
The buffer is a block of memory where the input from the keyboard (or other stream, such as a file) is temporarily stored.

Lets say you want to input an integer.
cin >> number;
The user enters a number, and presses [enter]. The buffer looks like this: "34\n"
When the cin statement reads the contents of the buffer, it stops at the last numeric character. Thus, the buffer afterwards looks like this: "\n".

If the program now has a getline statement, getline (cin, mystr); it will read the contents of the buffer, up to and including the '\n' character. The string mystr contains "" (an empty string) and the newline is discarded. Processing continues at the next statement.

Lets try that same process again, with different input.
The user enters a number, and may deliberately or accidentally type some other characters, and presses [enter].
cin >> number;
The user enters " 34 asdfg \n".
The cin statement ignores the leading whitespace, accepts the numeric values as the integer, and leaves the remaining characters in the buffer.
Afterwards, the buffer looks like this: " asdfg \n".
Now, the getline statement will again take everything up to the newline.
The string mystr contains " asdfg ".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>

using namespace std;

int main ()
{
    // Try entering aomething like "  34 asdfg "
    // when the integer is requested
    int number;
    string mystr;

    cout <<"Please enter an integer value." <<endl;
    cin >> number;
    cout << "The number was: "<< number << "." <<endl;
    cout << "Please enter a name." << endl;
    //cin.ignore(1000,'\n');     // try the program both with and without this line
    getline (cin, mystr);
    cout << "The name was: \"" << mystr << '\"' << endl;
    system("PAUSE");
    return 0;
}



The main point is that getting an integer or other variable using cin >> variable; reads just enough from the input buffer to satisfy the request. Anything else will remain in the buffer, including the newline character.

The getline() command is in some ways more straightforward, it reads everything up to and including the newline. The newline itself is not stored, but it is removed from the buffer.

Try the above program with line 17 re-instated (currently commented out).
Last edited on
I understand now. If I can comprehend correctly, the parameters of cin.ignore clears out 1000 characters or up until the new line correct?
That sounds about right.
http://www.cplusplus.com/reference/istream/istream/ignore/

Or you could do this, to ignore an unlimited number of chars:
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
What does simply doing cin.ignore() do then? Also, I'm sort of confused on the use of "::" (I guess since I'm still looking at tutorials I wouldn't understand it yet) for these functions. Is it another way of declaring them?
What does simply doing cin.ignore() do then?

Take a look at the reference for ignore(), http://www.cplusplus.com/reference/istream/istream/ignore/
If you call it with no parameters, it will use the default parameters.
That is, it will ignore at most one character, until the EOF value is met. Generally, EOF is relevant to files, rather than keyboard input.

So it's roughly correct to say it will ignore just one character.

Learn about default parameters here:
http://www.cplusplus.com/doc/tutorial/functions2/

Also, I'm sort of confused on the use of "::"

The :: is the scope resolution operator.
It's used when a name belongs to a particular class or namespace. In C++ the standard libraries such as <iostream> and so on belong to the std namespace.

There are three common ways to handle this.

1. put using namespace std; at the top of the program. This is often done in example programs, but despite that, it is not regarded as good practice.

2. put individual using statements for each of the required items from the particular namepace.
1
2
3
    using std::cout;
    using std::endl;
    using std::cin;

3. Explicitly specify the full name on every usage of such items, for example:
 
    std::cout << i << std::endl;

The third method is considered the safest, as there is no ambiguity over which name is intended to be used.
Last edited on
Would it be best to use the second or third method in handling code? How does using using namespace std; considered a bad practice?
When you put using namespace std;, it brings all of the items from the standard namepace into your program (depending on which #includes you have).

That is bad as it defeats the whole purpose of having separate namespaces in the first place. It increases the likelihood of naming conflicts between code you write yourself, and code in the standard library.
Which way would be best to use out of methods 2 and 3? I would consider 3 since it's the safest though I would like to use 2 as well.
Topic archived. No new replies allowed.