problem testing for numerics

Started by
8 comments, last by Joker2000 23 years, 9 months ago
Ok, I'm designing a bank in my current program that simply allows the user to deposit or withdraw money. However, I'm having a hard time assuring that the amount of money the user types in is numeric AND that it is a whole number. Here's the relevant code:

void menu_bank(player *ThePlayer, weapon *TheWeapon)
{
int withdraw;
int done = 0;
char menu_choice;

while(!done)
{
// bank options - "W" is withdraw

menu_choice = getch();

switch(toupper(menu_choice))
{
case 'W':
{
    cout << endl << "How much money to withdraw?\n";
    cin >> withdraw;
    if (!isdigit(withdraw))
    {
        cout << endl << "You can't use:";
        cout << endl << "Dollar signs, commas, periods, spaces, or any types of letters.";
        withdraw = 0;  // clear out their "crap" entry
        getch();
        break;
    }
    else
    {
        withdraw_check = ThePlayer->withdraw_money(withdraw);
        if ((withdraw_check == 0) || (withdraw_check == 1))
            cout << endl << "\nTransaction failed.";
        else
            done = 1;
            getch();
            break;
    }
  }
}
   
Ok, first of all, although it seems to work fine now, am I using the best technique to check for numerics (isdigit)? If I enter a numeric, it works fine. If I enter non-numerics, it seems to preform the test and it will give me the "You can't use: ..." stuff. However, after doing this it returns to the main bank menu, and the next time the user presses the "W" key to withdraw money, before it even let's them enter a number, it goes immediately to the "You can't use: ..." crap. It's like it skips the cin entirely and doesn't let them reenter the number. That's one bug in the program. And here's another, even weirder, one: If the user enters 0, it considers it to be non-numeric and gives them the "You can't use: ..." stuff. However, the next time the user presses "W", it DOES stop at the cin statement and allow them to enter another number. But, after the user has already entered 0, no matter what they enter the next time, even if it is all numerics, the isdigit test always fails. This is so strange to me...I don't see how this isn't working. If you need to see a little more of the code let me know. --- Joker2000 Stevie Ray Vaughan - The Legend Edited by - Joker2000 on 7/12/00 11:45:01 PM
Advertisement
What if you try using

    if (toupper(menu_choice) == ''W''){  cout << endl << "How much money to withdraw?\n";  cin >> withdraw;  if (!isdigit(withdraw))  {    cout << endl << "You can''t use:";    cout << endl << "Dollar signs, commas, periods, spaces, or any types of letters.";    withdraw = 0;  // clear out their "crap" entry    getch();  }  else  {    withdraw_check = ThePlayer->withdraw_money(withdraw);    if ((withdraw_check == 0) || (withdraw_check == 1))      cout << endl << "\nTransaction failed.";    else      done = 1;    getch();  } }}    


if this doesn''t work, try to flush the stdin...


..-=ViKtOr=-..
How do I flush the stdin and where exactly in the code would I do it?


---
Joker2000
Stevie Ray Vaughan - The Legend
I dont know why, but ive ALWAYS had problems like this when I use cin, cout, and getch() close together. You use flush just like cout. Ex: cout << "you cant do that" << flush;
What flush does: Usually, file handles and I/O streams( cout, cin) do not flush output until they encounter a carriage return or until an input operation occurs. The call to flush above would force "you cant do that" to appear before a carriage return or linefeed is encountered.

However, I usually could solve these problems by using the following:

cin.ignore(100, ''\n'');

This will ignore the first 100 characters in the input stream OR the first ''\n'' whichever comes first. It sounds like you''re getting a carriage return stuck in the input stream and I KNOW this will solve your problem. You just have to find out where it is happening and place the cin.ignore in the proper place.

hope that helped,
skitzo_smurf
"Innocent is just a nice way to say ignorant, and stupidity is ignorance with its clothes off."words of,skitzo_smurf
I had the same problem just a couple of days ago when i tried out Direct Input in my new program called "SuperUltraDeluxe Chatter 2000".

Well, to the point...
I solved it by making cin go to a string instead and then convert it to an int with atoi(). This will keep all non-digts out of the equation later on.

/CMN
"cin >> money;" leaves carriage return in the input buffer.

I think that could be connected to your problem.
A polar bear is a rectangular bear after a coordinate transform.
How does that leave a carriage return? I mean, it looks like a perfectly good statement to me. Or do you mean that lines prior to this one are leaving a carriage return?


---
Joker2000
Stevie Ray Vaughan - The Legend


Edited by - Joker2000 on July 13, 2000 1:41:42 PM
Hmmm, I was underthe impression that isdigit() is only used to check if a char is a number or not, not to check if an intege is a number.

Think about it. No matter what the user types, SOMETHING wil go into withdraw. And since withdraw is an int it will be some number, so why would isdigit(withdraw) ever return false???

The only time I''ve ever used isdigit is when i would read a string characterby characterand wantedto check if acharacter was a digit (0-9) or not

------------------------------
fclose(fp)
------------------------------
ByteMe95::~ByteMe95()My S(h)ite
getch() does not remove the character entered from stdin''s buffer, so the character that the user entered gets read at the next cin >> withdraw. Use getchar() instead.


int withdraw;cin >> withdraw;

I am not a C++ programmer, but I am suprised this works. If the >> operator does convert a string to an integer, there is no need to check for invalid characters, because they will be handled for you. And if it does, your call to isdigit will almost always fail. The isdigit function takes a single character as an argument and returns true if that character represents a digit.
Alrighty...I''ve edited a few things and now everything APPEARS to work correctly. I''m still anxious to see the kinds of errors my beta testers can generate, however. They are so good at that. In case you''re curious as to what I did to fix it, I simply read the withdraw amount into a string, tested it for all digits, and then converted it to an int if it passed. So, I pretty much did exactly as you guys told me...thanks a bunch you all!


---
Joker2000
Stevie Ray Vaughan - The Legend

This topic is closed to new replies.

Advertisement