|
-
September 23rd, 2002, 08:33 PM
#1
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
-
September 24th, 2002, 01:27 AM
#2
Instead of !Distance, check for cin.fail ();
Succinct is verbose for terse
-
September 24th, 2002, 09:52 AM
#3
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.
-
September 24th, 2002, 11:13 AM
#4
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
-
September 24th, 2002, 01:05 PM
#5
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.
-
September 24th, 2002, 01:20 PM
#6
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
-
September 24th, 2002, 01:54 PM
#7
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++
-
September 24th, 2002, 02:36 PM
#8
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;
}
-
September 24th, 2002, 03:01 PM
#9
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.
-
September 24th, 2002, 03:07 PM
#10
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.
-
September 24th, 2002, 03:33 PM
#11
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;
}
-
September 24th, 2002, 05:19 PM
#12
*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..
-
September 25th, 2002, 08:14 AM
#13
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.
-
September 25th, 2002, 10:33 AM
#14
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
-
September 25th, 2002, 04:00 PM
#15
Re: 123a problem
I think we should rename the "123a problem" to Anthony Mai problem .
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|