?
Solved

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

Posted on 2003-10-21
9
Medium Priority
?
370 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
9 Comments
 
LVL 22

Accepted Solution

by:
grg99 earned 240 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 260 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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 260 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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

777 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