Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

I've writtne a small program, part

Status
Not open for further replies.

stu74uk

Technical User
Jun 10, 2002
8
GB
I've written a small program, part of the program asks the user to input two numbers. How do I go about testing the numbers to check that the user did input an integer and not a character by accident. I ve tried the folowing:

label:

cout << &quot;Please enter a number: &quot;;
cin >> num1;

cout << &quot;Please enter another number: &quot;;
cin >> num2;

if ((num1 <= 47 || num1 >= 58) || (num2 <= 47 || num2 >= 58))
goto label;

using the goto statement, but if someone does enter a character the program just crashes. Hope somebody has some ideas.
 
Use the isdigit or isalpha functions in the ctype.h

Example:

#include <stdio.h>
#include <ctype.h> //required header file

void main()
{
char number;

printf(&quot;Enter a number: &quot;); //same as cout in C++
scanf(&quot;%c&quot;,&number);//same as cin in C++

if(isdigit((int)number))
printf(&quot;Its a number\n&quot;);
else
printf(&quot;Its not a number\n&quot;);
}

In addition, try to avoid using goto whenever possible.

Hope it works. =)

Zech
 
Please note that the above example tests only the first character of user input. You may need to make necessary changes if you want to test all characters of the user inputs.
 
A better solution would be to check the state of your stream before you try doing anything with what got input. For example:

[tt]int x;

while ( !( cin >> x ) )
{
cin.clear();
cin.ignore();
cout << &quot;\nNope. Try again: &quot;;
}
[/tt]

That says to try to get an integer from cin. If it failed (someone put in something it couldn't interpret as an integer), clear the error bits on cin and ignore anything left in the buffer (that character someone put in there) before trying again.
 
Cheers both of you for your help. Chipper when i tried your suggestion if i enter a number and hit enter, the program goes to the next line and i have to enter the number again for the program to process the information. Do you have any suggestions to rectify this or is there nothing I can do?
 
I tried the code on MSVC++ and I couldn't get it to repeat the behavior you described. However, I did notice an error in my code. When I said &quot;cin.ignore()&quot;, I was assuming only one character would be entered. I should have said something like &quot;cin.ignore( 80, '\n' )&quot;, which ignores all characters left on the buffer (unless someone typed over 80 characters by mistake).

The code still works fine for me with the first version, it just prints too many error messages when you enter several characters. Try changing that and see if it fixes your problem. If not, let me know what compiler and library you're using and I'll see if I can find anything that could be causing it.
 
Hi Stu,

I don't quite understand the problem that you are trying to fix here. Is it the newline thing or having to re-enter the information that bothers you?

Anyway, if it is the newline problem, you can always use clrscr (to clear the screen and then re-display your message) or gotoxy (to reset the cursor position) functions in conio.h. However, I can't find their equivalents in VC++ standard library so you may try using the system function (like what I did in the codes below) or look for their Win32 API equvalents.

If it is having to re-enter the information that bothers you, you can always create a function that screens out the non-integers in the user inputs.

Since I am not sure what it is that you are trying to do, I have included both options in the codes below:with users having to re-enter the information and with the program screening out the non-integers. You can ONLY use EITHER one of them and NOT both of them. Comment out the one that you don't need.

Let me know if the code below solves your problem =) Additionally, it checks up to 50 characters of user inputs.

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

void main()
{
char buffer;
char input[50];//to store user inputs
int a=0, b=0;
bool isnumber=true;

while(a<50) //a<50 is to prevent buffer overflow
//you can change it to 'while(true)'
//if you care less about buffer overflow
{
printf(&quot;Enter a number: &quot;);

while((buffer=getchar())!='\n')//while character is not a newline
{
/****************************************************/
//use the following codes if you want users to re-enter
//the inputs if they enter non-integers

if(isalpha((int)buffer))//if input contains alphabets
isnumber=false; //it's not a number
input[a]=buffer;
a++;

/***************************************************/

/***************************************************/
/* Use the following codes if you want the program to
automatically filter user inputs for integers and
screen out the characters
DON'T FORGET TO COMMENT OUT THE ABOVE CODES IF YOU
DECIDE TO USE THE CODES BELOW.

if(isdigit((int)buffer))//only if inputs is integer
{
input[a]=buffer; //store the user inputs
a++;
}
/*****************************************/
}

if (isnumber==true)//if inputs contains all numbers
{
printf(&quot;Okay\n&quot;);
printf(&quot;You have entered &quot;);

while(b<a)//display inputs
{
printf(&quot;%c&quot;,input);
b++;
}
printf(&quot;\n&quot;);

break;
}
else
{
isnumber=true;//reset the isnumber flag
a=0;//reset the a count

system(&quot;cls&quot;);//You can clear the entire screen
//or re-set the cursor position.
//You can use clrscr or gotoxy functions
//in conio.h, but I can't find their
//equivalents in standard VC++ library.
//You may want to look for their Win32 API
//equivalents

printf(&quot;Re-enter the number\n&quot;);
}
}
}
 
All right, this TGL stuff is annoying. I have just notice that the '' part is missing. So I will paste the code again.

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

void main()
{
char buffer;
char input[50];//to store user inputs
int a=0, b=0;
bool isnumber=true;

while(a<50) //a<50 is to prevent buffer overflow
//you can change it to 'while(true)'
//if you care less about buffer overflow
{
printf(&quot;Enter a number: &quot;);

while((buffer=getchar())!='\n')//while character is not a newline
{
/****************************************************/
//use the following codes if you want users to re-enter
//the inputs if they enter non-integers
/*
if(isalpha((int)buffer))//if input contains alphabets
isnumber=false; //it's not a number
input[a]=buffer;
a++;

/***************************************************/

/***************************************************/
/* Use the following codes if you want the program to
automatically filter user inputs for integers and
screen out the characters
DON'T FORGET TO COMMENT OUT THE ABOVE CODES IF YOU
DECIDE TO USE THE CODES BELOW.
*/
if(isdigit((int)buffer))//only if inputs is integer
{
input[a]=buffer; //store the user inputs
a++;
}
/*****************************************/
}

if (isnumber==true)//if inputs contains all numbers
{
printf(&quot;Okay\n&quot;);
printf(&quot;You have entered &quot;);

while(b<a)//display inputs
{
printf(&quot;%c&quot;,input);
b++;
}
printf(&quot;\n&quot;);

break;
}
else
{
isnumber=true;//reset the isnumber flag
a=0;//reset the a count

system(&quot;cls&quot;);//You can clear the entire screen
//or re-set the cursor position.
//You can use clrscr or gotoxy functions
//in conio.h, but I can't find their
//equivalents in standard VC++ library.
//You may want to look for their Win32 API
//equivalents

printf(&quot;Re-enter the number\n&quot;);
}
}
}

 
I think his problem was just that, using my code, he had to input a number twice to get the program to do anything. i.e. As if the first value was simply ignored.

Given that there's actually an ignore function in my code, I'd say that's a likely cause of the problem, but I don't see how it would be getting called after a number got input.

Stu, does your current code look like my original, or did you modify it? If you did, make sure the flow of logic doesn't take it into the ignore when cin gets an integer.
 
I wonder if he left his original cin >> num1 in his code. Stu, you'll have to take it out for the loop to work correctly.
 
Heh, I've had so many problems with cin, I just overrode it with my own :) Anyway, let's not forget where we came from!
Here's a good ole (quasi)C function that does just fine. I'll leave it up to the poster to cin-ize it if he wishes to...

Code:
bool get( int& value ) {
 char buff[256];
 fgets(buff, 256, stdin);
 char * c = buff;
 bool found = false;
  do{
   if(isdigit(*c)) 
    found = true;
   else
    break;  
  }while(*(c++)); 
 value = atoi(buff); 
 return found; 
}




int main() {

 int number;
 cout << &quot;Enter a valid number: \n\n   &quot;;
 while(!get(number)) {
 cout << &quot;Please re-enter your input...\n\n    &quot;; 
 }
 cout << &quot;Thanks. You entered &quot; << number << endl;
 system(&quot;pause&quot;);
 return 0;
 }
 
Cheers for all your replys I,ve not tried most of them yet as I've been changing my calculator program's code to use functions and case statements, once I've figured out where to put your code I'll let you know how they worked.
 
All this C code to get a string and test the digits works, but it's way more complicated than it has to be.

If you must use C, scanf has a surprisingly little-known feature: it returns the number of arguments it was able to read.

So in the code:

[tt]int x, n;
n = scanf( &quot;%d&quot;, &x );
[/tt]

n will be 1 if it got the integer and 0 if it didn't.
 
Good point. But personally, I have always disliked the scanf family for some reason, always preferring to parse the string myself...glad you pointed that out though...
 
C++ is essentially C with additional OOP features, Stu. You can't expect to know only C++ without knowing C. Most people who use C++ would normally use C to a certain degree in their codes.
 
Remember that STL != C++. (In all of my professional apps their isn't a single call to that library either! Every class/stream object, etc, is hand-coded by me. Thus, no surprises! :) ).
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top