Solved

Avoid fail state of the input stream - inputting a char into an int!!

Posted on 2003-10-21
9
366 Views
Last Modified: 2010-04-02
I am working on a Homework assignment and need this ASAP.  I can email my professor but will not get an answer until the morning, most likely.

What is the common procedure to avoid entering the fail state of the input stream?  I am writing a program, which is actually a simple game, and it depends on the user entering an integer value to be subtracted from an existing integer value.  This is contained in a while loop, which runs until the remaining integer is 1.

How can I catch a user's mistake when he enters a non-integer like "a"?  My professor mentioned something about validating using a char first, but then how would I even test to see if the char is an integer or not?

I know I can say if ( !istream ) then output an error.... or something like that... but of course now the input stream is in the fail state and the entire program must be restarted in order to restore that stream.  Do I have everything correct?  What should I do, besides just yelling at the user after he enters a character in place of an integer, and breaking the program, so that I can loop back and say hey you can't enter that, enter an integer now... without breaking that input stream.

Thanks in advance!  Hopefully I have worded this clearly...
0
Comment
Question by:jonnyz0109
9 Comments
 
LVL 22

Accepted Solution

by:
grg99 earned 60 total points
ID: 9595320
The trick is to not read an integer, but read the input as a char.  Then validate the character as being a digit.  Then if and onyl if it's a digit, append that digit to some string variable you're keeping.    Then when they press <Enter> or whatever to signal they're done, convert the string to an integer with something like atoi().
0
 
LVL 4

Author Comment

by:jonnyz0109
ID: 9595331
1) How do I validate the character as being a digit?
2) Can I use a string variable that is not an array?
3) I don't think we have "learned" atoi() yet... anything else I can use?

Thanks
0
 
LVL 15

Assisted Solution

by:efn
efn earned 65 total points
ID: 9595419
> 1) How do I validate the character as being a digit?

There's an isdigit function in the standard library.

> 2) Can I use a string variable that is not an array?

Yes.

> 3) I don't think we have "learned" atoi() yet... anything else I can use?

You could use a stringstream or the library function strtol, but neither of these is likely to be significantly easier.

The approach grg99 gave you is pretty standard and is probably what your professor was suggesting, but there is another way.  Once an input stream goes into the failed state, it is not necessarily stuck in that state for the remaining life of the program.  The failed state is just a bit that you can clear with the istream::clear() function.  Then you can read from the stream again.  The tricky part is that the bad input will still be sitting in the stream, so you have to read past it and throw it away before you can read the next real input from the user.  The istream::ignore() function is handy for this.  Typically one tells this function to ignore everything up to the end of a line.

--efn
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 4

Author Comment

by:jonnyz0109
ID: 9595496
so here is what I have... not sure how nice it will look without a good courier-like font...

int n = 0, pileSize = [some random integer]
while ( pileSize > 1 )
{
      cout << "\nPile Size: " << pileSize << endl;
      cout << "Your Move: ";
      cin >> n;

                if ( !istream)
                {
                                istream::clear();
>>                            ..... AND DO WHAT HERE??                         <<

      if ( ( n == 0 ) || ( n > ( pileSize / 2 ) ) )
      {
            cout << "You have made an illegal move.\nYou must take at least 1 marble and no more than half the pile size." << endl;
      }
      else /* if ( ( n > 0 ) && ( n <= ( pileSize / 2 ) ) ) */
      {
            pileSize = pileSize - n;
      }
0
 
LVL 15

Assisted Solution

by:efn
efn earned 65 total points
ID: 9595893
Your input stream is named "cin", so that is the object to name when you want to do something to the stream.

if (!istream)

won't work.  It should be something like

if (!cin)

or

if (cin.fail())

Similarly, you want to code cin.clear().

After that, you need a call to cin.ignore to tell it to read past the bad input, probably up to the end of the input line.  You can read about this function here:

http://www.cplusplus.com/ref/iostream/istream/ignore.html

You can look for the newline character '\n' marking the end of an input line.

--efn
0
 
LVL 4

Author Comment

by:jonnyz0109
ID: 9600255
OK Well I'm still not sure how to do that... but I got an email from my professor.

I plan to go over this in class today:
 
1.  to test whether a char is numeric use isdigit(myChar)
2. to convert a char, after doing the above test, use noMarbles = int(myChar - '0') where noMarbles is an int and '0' is zero ... you will need to derive an algorithm to convert the stream of chars to a decimal number.

I'll see what that means later today in class.
0
 
LVL 4

Author Comment

by:jonnyz0109
ID: 9600264
BTW, finished the game for everything except for this one thing... I figured I could always go back and fix it.  Currently I'm just using an int and when I enter a character it goes crazy   :o)
0
 
LVL 4

Expert Comment

by:havman56
ID: 9606136


when user enters a character u can detect

input stream

use sprintf to convert the anydata to the buffer and check the buffer whether the values
are in character range if it is integer then  then inform user u entered integer.

data what he enters

sprintf(buffer,"%d",data);

have ur logic wriiten absed on it

0
 
LVL 4

Author Comment

by:jonnyz0109
ID: 10442613
Cleaning up old questions and forgot I had this one.  My professor ended up giving me the solution... basically, input into a char MyChar and use the following in a loop.

MyInt = (MyInt * 10) + (MyChar - '0')

Where MyInt is initialized to 0.  The state to end the loop is when MyChar = '\n' .  What I wasn't realizing when I opened this question was that if you input an entire line, and you're inputting into a char, it only reads one character at a time and leaves the rest in the stream.  So there is no need to do anything fancy, just keep increasing the existing value by ten and add the next one on until the end line is reached.

Thanks all :o)
0

Featured Post

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question