Solved

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

Posted on 2003-10-21
9
363 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
 
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Suggested Solutions

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

760 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now