CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    Join Date
    Sep 2002
    Posts
    11

    user input datatype check?

    hey hey.. can anyone answer this simple question for me?

    i have a program that prompts the user to input a number. I then want to check to make sure the user inputs a number and not a character of some kind yet I am unsure of how to do this.

    Could someone tell me what i need to do?
    I tried the following.

    double Distance;
    cout << "Enter distance: ";
    cin >> Distance;

    while(!Distance || Distance < 0)
    {
    cout << "Error";
    cout << "Enter distance: ";
    cin >> Distance;
    }

    the following code works if i enter a negative number.. it will keep prompting me to enter the distance again. But if i type a letter or any other character i get an error at !Distance
    any help would be appreciated

  2. #2
    Join Date
    Jun 2002
    Location
    Letchworth, UK
    Posts
    1,020
    Instead of !Distance, check for cin.fail ();
    Succinct is verbose for terse

  3. #3
    Join Date
    Sep 2002
    Posts
    11
    ahh.. thats what i needed.. thnx for the help.. all good now

    edit: oop thought was all good but still having problems

    Code:
    double getInput()
      {
        double Input;
        static bool Continue = false;
    
        while (Continue == false)
          {
            cout << "Input the distance between yourself and the rainbow: ";
            cin >> Input;
    
            if (cin.fail() || Input < 0)
              {
                cout << endl << "Error" << endl;
              }
            else
              {
                Continue = true;
              }
           }
        return Input;
      }
    in the above code:
    --if i type a positive number it returns that number.
    --if i type a negative number it displays "Error" and re-prompts
    user to input another number.
    --if i type a character or symbol the program displays "Error"
    "Input the distance between yourself and the rainbow: ";
    over and over in an infinite loop. It doesn't give the user a
    chance to re-enter another number.
    I can't figure out why.. any ideas anyone?
    Last edited by tegwin; September 24th, 2002 at 10:56 AM.

  4. #4
    Join Date
    Jun 2002
    Location
    Letchworth, UK
    Posts
    1,020
    If it fails, call cin.clear() before you do another input.

    Nice message: I've never had that one before. What compiler are you using?
    Succinct is verbose for terse

  5. #5
    Join Date
    Sep 2002
    Posts
    11
    Using C++ Builder 5 EE as my compiler... BTW where are you getting these function declarations from?!? U know them or are they listed in the visual c++ documentation or you looking through the library files or somethin? I've checked MSDN documentation at microsoft but couldn't locate a list of functions for cin.

    Ah crap... just tried it and getting same results.. this is weird and I cannot figure out what the problem is.. i remove the cin.fail() and see what happens when i enter a character.. and i get an invalid point-float variable error.. don't know why a negative number works fine but a character goes into infinite loop.. both inputs should run the exact same code... arggggggg
    I guess it could be the compiler... i just don't know anymore..
    Last edited by tegwin; September 24th, 2002 at 01:13 PM.

  6. #6
    Join Date
    Jun 2002
    Location
    Letchworth, UK
    Posts
    1,020
    The function declarations are part of ios: it is the abstract stream class. All the stream stuff is derived from ios.

    I'll try out your code on VC++ just to see whether I get the same over the rainbow bit.
    Succinct is verbose for terse

  7. #7
    Join Date
    Sep 2002
    Posts
    11
    i'm confused... i've debugged my program step by step.

    If cin.fail() returns true then the next time it comes to cin >> Input;
    it just skips right over it.. however if cin.fail() returns false the next time cin>>Input; comes around the program pauses allowing for input thats why negative numbers work fine. i've tried re-ordering the program but nothin' workin'... there wouldn't by any chance be a cin function that would force the program to pause would there?
    also when i try cin.clear() it does some weird crap when it comes to cin >> Input the first time around... even though i don't call cin.clear() until later in the program.. someone just shoot me now and get it over with....

    P.S. very interested on your results with Visual C++

  8. #8
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725
    try to ignore() the rest of the line , as ...

    Code:
    double getInput()
      {
        double Input;
        static bool Continue = false;
    
        while (Continue == false)
          {
            cout << "Input the distance between yourself and the rainbow: ";
            cin >> Input;
    
            if (cin.fail() || Input < 0)
              {
                cout << endl << "Error" << endl;
    
                cin.clear();
                cin.ignore(80,'\n');    // ignore rest of line
              }
            else
              {
                Continue = true;
              }
           }
        return Input;
      }

  9. #9
    Join Date
    Sep 2002
    Posts
    11
    Bingo!!! uh.. i mean.. that did that trick... don't know how you thought of that... there must be an easier way to check if user input is correct.... but hey this works.. and thats all that matters... thnx for the help
    Last edited by tegwin; September 24th, 2002 at 03:09 PM.

  10. #10
    Join Date
    Jul 2002
    Location
    St. Louis, MO
    Posts
    484
    A "Do-While" loop would cut down on a little of the code. Just interjecting because anytime I have ever done user input verification I have used a "Do-While" loop.

  11. #11
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725
    A couple of notes :

    1) I don't think you want the variable, Continue,
    to be static. Currently, it will not input more
    than once :

    Code:
        double d1,d2;
    
        d1 = getInput();
        d2 = getInput();


    2) If the user enters something like 123a, the function
    will return 123, and set the input position at the "a", which
    will cause an error if getInput() is called a second time.
    So you might want to add another ignore() even when successful.

    Code:
    double getInput()
      {
        double Input;
        bool Continue = false;
    
        while (Continue == false)
          {
            cout << "Input the distance between yourself and the rainbow: ";
            cin >> Input;
    
            if (cin.fail() || Input < 0)
              {
                cout << endl << "Error" << endl;
    
                cin.clear();
                cin.ignore(80,'\n');    // ignore rest of line
              }
            else
              {
                Continue = true;
              }
           }
           cin.ignore(80,'\n');    // ignore rest of line
       return Input;
      }

  12. #12
    Join Date
    Sep 2002
    Posts
    11
    *ding ding* "Idiot vs Rest of the World" Round 2

    yeah i was just noticing what you were talking about. I only call
    getInput() once in my program.. but good note for the future with that extra ignore..

    I just realized the 123a problem as well and was going to ask if anyone knows how to get around it.. I would like it to return an error if 123a is typed in but like u said it will return 123.
    I tried cin.getline() but i don't think it works with double datatypes. I also tried
    cin >> value1 >> value2; and tried to do some checking but couldn't find a way to make it work.
    Might try using a String with cin.getline() and cast it to a double and then do some kind of checking..
    just wanted to know if anyone knows how to avoid 123a problem so i don't spend half an hour trying to find a solution..

  13. #13
    Join Date
    Jul 2002
    Location
    American Continent
    Posts
    340
    I just realized the 123a problem as well and was going to ask if anyone knows how to get around it.. I would like it to return an error if 123a is typed in but like u said it will return 123.
    There is alternative solution. But there is ABSOLUTELY NO CURE as long as your code contains something remotely ressembles:
    Code:
        cin >> myDoubleInput;
    Something is fundamentally wrong with the idea of standard stream IO, especially when it is used to read keyboard input. Look at this form of code:

    Code:
        outputFile   << str0 << str1 << int2 << obj3 << vector4;
        //...
        inputFile   >> str0 >> str1 >> int2 >> obj3 >> vector4;
    The problem is once data of specific type is output, it all concascade into one big chunk of binary bytes with no type information contained in them whatsoever. There is no string, there is no integer, there is no structure, there are only bytes that could be any thing.

    So when you read it back in, how do you know what specific data type each byte belongs to? You don't! In the above example, if str0 is "Hello" and str1 is "world", You end up with "Helloworld" in the file, so when you read it back in, should "Helloworld" be read in as one string or two string, or something else?

    The >> operator is type casting of the worst category! On the left side of the operator is a stream object which inputs bytes, on the right size it could be any data type. Basically you are trying to cast bytes to any arbitrary data type, no wonder it is error prone.

    It's even worse in the case of keyboard input. The user could type trash but the code would presume the data is of expected type, in expected sequence. It would never work, even if the user types correctly. This is an example which would NOT give what you want:
    Code:
     cout << "Please enter your full name" << endl;
     cin >> firstName >> middleName >> lastName;
    The correct approach, is to treat user input as the data type it is. The user does not enter a double or float, the user does not enter a signed or unsigned 32 bits integer.

    All that the user does, is entering a string, followed by a punch on the ENTER key. i.e., the user input should always be read in first as LINES. And then you try to parse lines to exam whether the line contains expected input in expected format. And if it does, then parse the line to get the input. Exactly how you parse the line depends on what the format of the input is, there is no generic way of doing it.

    So first you read in the whole line "123a", and parse it as a floating point number one character at a time, and when you done with the parsing, determine if there are additional stuff following it, and there is an "a", so you know it is an error. The code should be pretty easy to write.

  14. #14
    Join Date
    Apr 1999
    Posts
    27,449
    The problem is once data of specific type is output, it all concascade into one big chunk of binary bytes with no type information contained in them whatsoever. There is no string, there is no integer, there is no structure, there are only bytes that could be any thing.
    And what does this have to do with iostreams, specifically? Just your chance to rail against iostreams, when there really isn't a reason to do so? This problem exists if you use <stdio.h>
    So when you read it back in, how do you know what specific data type each byte belongs to? You don't! In the above example, if str0 is "Hello" and str1 is "world", You end up with "Helloworld" in the file, so when you read it back in, should "Helloworld" be read in as one string or two string, or something else?
    He/she who writes the stream correctly knows how to read the stream correctly. Again, this has nothing specificaly to do with iostreams, the same "problem" exists with <stdio.h>.
    The >> operator is type casting of the worst category! On the left side of the operator is a stream object which inputs bytes, on the right size it could be any data type. Basically you are trying to cast bytes to any arbitrary data type, no wonder it is error prone.
    And stdio.h isn't error prone, if not more so?

    A database library has a C++ wrapper that overloads << for writing the database object to a file and >> for reading the data base back into the object. Is that a good usage of streams?

    If you don't know what input to expect, the solution is as you stated -- read in as a string and parse the data. This has been the solution since the earliest days of computer languages and I/O. The question is what if you do know how to read and write the object correctly, i.e. the input / output is well defined, as in the database library example?

    Regards,

    Paul McKenzie

  15. #15
    Join Date
    Sep 2002
    Posts
    33

    Re: 123a problem

    I think we should rename the "123a problem" to Anthony Mai problem .

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured