cin input (newbie question)

B

B. Fletcher

Hi
I'm currently converting a console Java application into C++, and I am
having a problem. I am a newbie at C++ and any help would be apreaciated.

My code says;
int marbles;
....
cin >> marbles;
If I type a word into the program, the program goes into an infinite loop. I
know this is because I'm using the >> version of cin, but the alternatives
dont allow for:
If the user doesn't enter an int, I want the program to display a promt to
the user. But if there is an error/EOF while reading, I want a different
prompt displayed.

Btw, I am using MingW g++.exe to compile. the version of MingW I am using
came with Borland C++ BuilderX.

Does anyone have any suggestions on the method I can use?
Any help would be greatly appreaciated.

B.
 
S

Sharad Kala

B. Fletcher said:
Hi
I'm currently converting a console Java application into C++, and I am
having a problem. I am a newbie at C++ and any help would be apreaciated.

My code says;
int marbles;
...
cin >> marbles;
If I type a word into the program, the program goes into an infinite loop. I
know this is because I'm using the >> version of cin, but the alternatives
dont allow for:
If the user doesn't enter an int, I want the program to display a promt to
the user. But if there is an error/EOF while reading, I want a different
prompt displayed.

Look at the following -
cin.good ()
cin.clear ()
and cin.ignore().

Basically cin goes into a fail state on any kind of errors. So you need to set
the stream into good state again and ignore the extra unwanted characters.

-Sharad
 
K

Karl Heinz Buchegger

Sharad said:
Look at the following -
cin.good ()
cin.clear ()
and cin.ignore().

Basically cin goes into a fail state on any kind of errors. So you need to set
the stream into good state again and ignore the extra unwanted characters.

To the OP:

That's one way to do it.
Another way would be to not input into an int at all.
Read everything as a string and figure out if the string
entered contains only digits (or whatever you want the user
to enter), and do the conversion on your own. (eg. by using
a string stream).
 
R

red floyd

B. Fletcher said:
Hi
I'm currently converting a console Java application into C++, and I am
having a problem. I am a newbie at C++ and any help would be apreaciated.

My code says;
int marbles;
...
cin >> marbles;
If I type a word into the program, the program goes into an infinite loop. I
know this is because I'm using the >> version of cin, but the alternatives
dont allow for:
If the user doesn't enter an int, I want the program to display a promt to
the user. But if there is an error/EOF while reading, I want a different
prompt displayed.

operator>> allows you to check the result.

if (cin >> marbles)
{
// I got marbles!
}
else if (cin.eof())
{
// EOF
}
else // disclaimer, I can't remember all the statuses for std::istream
{
// error or bad input
}
 
K

Kevin Goodsell

B. Fletcher said:
Hi
I'm currently converting a console Java application into C++, and I am
having a problem. I am a newbie at C++ and any help would be apreaciated.

My code says;
int marbles;
...
cin >> marbles;
If I type a word into the program, the program goes into an infinite loop.

Robust input handling usually means reading a line at a time (as others
have suggested). The problem (well, one of them) with >> is that it
tends to handle surprising input in surprising ways. You've discovered
one such case. Also, consider what happens if I enter multiple (valid)
input items on one line. The next time a prompt should appear, my old
input is already available and will be used instead of the program
waiting for new input.

You can work around the problems with >> (or ignore them, if you don't
need robust input handling), but you may find it easier to just read an
entire line, check the validity of it, then interpret the data
appropriately. Use std::getline(std::istream &, std::string &) for
reading a line.

-Kevin
 
A

Adrian Parker

B. Fletcher said:
Hi
I'm currently converting a console Java application into C++, and I am
having a problem. I am a newbie at C++ and any help would be apreaciated.

My code says;
int marbles;
...
cin >> marbles;
If I type a word into the program, the program goes into an infinite loop. I
know this is because I'm using the >> version of cin, but the alternatives
dont allow for:
If the user doesn't enter an int, I want the program to display a promt to
the user. But if there is an error/EOF while reading, I want a different
prompt displayed.

Btw, I am using MingW g++.exe to compile. the version of MingW I am using
came with Borland C++ BuilderX.

Does anyone have any suggestions on the method I can use?
Any help would be greatly appreaciated.

I use this. It's always worked for what I need, maybe not in your case
though.

cin >> marbles;

while(cin.peek() != 10)
{
cin.clear();
cin.ignore(80, '\n');

cout << "Sorry, the number you entered was not valid." << endl;
cout << "Please enter an integer: ";
cin >> marbles;
}


Adrian
 
K

Kevin Goodsell

Adrian said:
I use this. It's always worked for what I need, maybe not in your case
though.

cin >> marbles;

while(cin.peek() != 10)
{
cin.clear();
cin.ignore(80, '\n');

cout << "Sorry, the number you entered was not valid." << endl;
cout << "Please enter an integer: ";
cin >> marbles;
}

Both of the magic numbers in your code are ill-advised. If you want to
look for a newline, just use '\n'. If you want to discard all input up
to a delimiter, use std::numeric_limits<std::streamsize>::max(). Or at
least something a lot larger than 80... (the streamsize max() suggestion
acts like infinity for the ignore() function).

I think you could probably do better with something like this:

while (!(cin >> marbles))
{
if (cin.eof() || cin.bad())
{
// No sense in trying to continue.
throw "something reasonable";
}

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

// Repeat prompt here.
}

This reveals a few of the problems with the above code. In particular,
it continued to prompt even if end-of-file is encountered. This should,
I believe, put it in an infinite loop. Continuing when badbit has been
set is also questionable.

Although, my version doesn't handle extra data on the input line the way
yours does. That would take a bit more work.

-Kevin
 
A

Adrian Parker

Kevin Goodsell said:
Both of the magic numbers in your code are ill-advised.

When will the newline character in an int not be 10?

If you want to
look for a newline, just use '\n'. If you want to discard all input up
to a delimiter, use std::numeric_limits<std::streamsize>::max(). Or at
least something a lot larger than 80... (the streamsize max() suggestion
acts like infinity for the ignore() function).

I think you could probably do better with something like this:

while (!(cin >> marbles))
{
if (cin.eof() || cin.bad())

I'm told that cin.eof is a bad practice, although I do not understand why.

{
// No sense in trying to continue.
throw "something reasonable";
}

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

// Repeat prompt here.
}

This reveals a few of the problems with the above code. In particular,
it continued to prompt even if end-of-file is encountered. This should,
I believe, put it in an infinite loop. Continuing when badbit has been
set is also questionable.

If it's user input though, why worry about EOF? The user can as easily hit
C-c as C-z (Windows bindings anyway).


Adrian
 
K

Kevin Goodsell

Adrian said:
When will the newline character in an int not be 10?

On any system that uses a character set in which it is something else.
Why assume it will be 10? It only serves to decrease portability and
clarity.
I'm told that cin.eof is a bad practice, although I do not understand why.

It's bad to loop on cin.eof(), but checking it after an error has
occurred is good. You don't loop on it because it may not be true at the
time you expect it to be. After reading the last character, the flag
might not yet be set. Instead, it will be set after you attempt to read
one more (non-existent) character.

There's a FAQ entry about this, if you haven't read it:

http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5

If it's user input though, why worry about EOF? The user can as easily hit
C-c as C-z (Windows bindings anyway).

If you think it's acceptable for your program to force the user to
terminate the program in an unusual way, and enter an infinite loop if
they try to terminate the input in the usual way, or if they pipe in a
file, then I suppose you can do that. I consider it sloppy and wouldn't
do it myself, nor would I want to use a program that behaves that way.

-Kevin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top