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
, and scanf
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 use atoi
, you probably aren't allowed to use strtol
either. So you'll need to examine each character in the string. The safe way to check for digit values is to use the isdigit
library function (there are also the isodigit
and isxdigit
functions for checking octal and hexadecimal digits, respectively), such as
while (*input && isdigit(*input))
input++;
(if you're not even allowed to use isdigit
, isodigit
, or isxdigit
, 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 leading 0x
. 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
- If the first non-whitespace character is not a '-', '+', '0', or non-zero decimal digit, then this is not a valid integer string;
- If the first non-whitespace character is '-', then this is a negative value, otherwise we assume a positive value;
- If the first character is '+', then this is a positive value;
- If the first non-whitespace and non-sign character is a non-zero decimal digit, then the input is in decimal format, and you will use
isdigit
to check the remaining characters;
- If the first non-whitespace and non-sign character is a '0', then the input is in either octal or hexadecimal format;
- If the first non-whitespace and non-sign character was a '0' and the next character is a digit from '0' to '7', then the input is in octal format, and you will use
isodigit
to check the remaining characters;
- If the first non-whitespace and non-sign character was a 0 and the second character is
x
or X
, then the input is in hexadecimal format and you will use isxdigit
to check the remaining characters;
- If any of the remaining characters do not satisfy the check function specified above, then this is not a valid integer string.