The catch is that I cannot use atoi or any other function like that (I'm pretty sure we're supposed to rely on mathematical operations).
int num;
scanf("%d",&num);
if(/* num is not integer */) {
printf("enter integer");
return;
}
I've tried:
(num*2)/2 == num
num%1==0
if(scanf("%d",&num)!=1)
but none of these worked.
Any ideas?
There are several problems with using
scanf
with the%d
conversion specifier to do this:If the input string starts with a valid integer (such as "12abc"), then the "12" will be read from the input stream and converted and assigned to
num
, andscanf
will return 1, so you'll indicate success when you (probably) shouldn't;If the input string doesn't start with a digit, then
scanf
will not read any characters from the input stream,num
will not be changed, and the return value will be 0;You don't specify if you need to handle non-decimal formats, but this won't work if you have to handle integer values in octal or hexadecimal formats (0x1a). The
%i
conversion specifier handles decimal, octal, and hexadecimal formats, but you still have the first two problems.First of all, you'll need to read the input as a string (preferably using
fgets
). If you aren't allowed to useatoi
, you probably aren't allowed to usestrtol
either. So you'll need to examine each character in the string. The safe way to check for digit values is to use theisdigit
library function (there are also theisodigit
andisxdigit
functions for checking octal and hexadecimal digits, respectively), such as(if you're not even allowed to use
isdigit
,isodigit
, orisxdigit
, then slap your teacher/professor for making the assignment harder than it really needs to be).If you need to be able to handle octal or hex formats, then it gets a little more complicated. The C convention is for octal formats to have a leading
0
digit and for hex formats to have a leading0x
. So, if the first non-whitespace character is a 0, you have to check the next character before you can know which non-decimal format to use.The basic outline is
isdigit
to check the remaining characters;isodigit
to check the remaining characters;x
orX
, then the input is in hexadecimal format and you will useisxdigit
to check the remaining characters;This method works for everything (integers and even doubles) except zero (it calls it invalid):
The while loop is just for the repetitive user input. Basically it checks if the integer x/x = 1. If it does (as it would with a number), its an integer/double. If it doesn't, it obviously it isn't. Zero fails the test though.
I developed this logic using gets and away from scanf hassle:
num
will always contain an integer because it's anint
. The real problem with your code is that you don't check thescanf
return value.scanf
returns the number of successfully read items, so in this case it must return 1 for valid values. If not, an invalid integer value was entered and thenum
variable did probably not get changed (i.e. still has an arbitrary value because you didn't initialize it).As of your comment, you only want to allow the user to enter an integer followed by the enter key. Unfortunately, this can't be simply achieved by
scanf("%d\n")
, but here's a trick to do it:First ask yourself how you would ever expect this code to NOT return an integer:
You specified the variable as type integer, then you
scanf
, but only for an integer (%d
).What else could it possibly contain at this point?
I looked over everyone's input above, which was very useful, and made a function which was appropriate for my own application. The function is really only evaluating that the user's input is not a "0", but it was good enough for my purpose. Hope this helps!