>is this possible?
Certainly.
>crashproof?
More difficult. This is a good start (not really elegant, but it works):
Code:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
static size_t numberOfDigits(int val)
{
size_t n = 0;
while (val)
{
++n;
val /= 10;
}
return n;
}
static int validNumber(char *s)
{
size_t len = strlen(s);
if (len > numberOfDigits(INT_MAX))
return 0;
while (*s)
{
if (!isdigit(*s++))
return 0;
}
return 1;
}
int main(void)
{
char buff[BUFSIZ];
int num;
printf("Enter a number: ");
fflush(stdout);
if (fgets(buff, sizeof (buff), stdin))
{
char *newline = strrchr(buff, '\n');
if (newline)
*newline = '\0';
if (validNumber(buff))
{
num = (int)strtol(buff, 0, 0);
printf("Your number (%d) was valid\n", num);
}
}
return 0;
}
Another possibility is to ignore prevalidation and use the return codes from strtol to get your bulletproof conversion (code "borrowed" from Jack Klein ):
Code:
/* file usestrtol.c
*
* 15-Jul-2002
* (C) 1999 by Jack Klein
* All rights reserved
*
* License granted for free non-commercial use
*
* Description:
*
* this program demonstrates the use of the standard
* library function strtol() prototpyed in <stdlib.h>
* to obtain and validate a signed integer value from the
* standard input stream
*
* C++ notes:
*
* On newer, ANSI/ISO Standard Conforming C++ compilers,
* the function strtol() is prototpyed in <cstdlib> and
* is in the std namespace
*
* The strtol() function operates with an array of constant
* characters as its source which could be read with the
* cin.getline() member function instead of the C library
* fgets() function
*
* It can even be called with the pointer returned by the
* c_str() member function for a std::string
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
int main(void)
{
char buff [25];
char *end_ptr;
long long_var;
int int_var;
for ( ; ; )
{
printf("Enter an int, return only to quit: ");
fflush(stdout);
fgets(buff, sizeof buff, stdin);
if (buff [0] == '\n')
{
break;
}
errno = 0;
long_var = strtol(buff, &end_ptr, 0);
if (ERANGE == errno)
{
puts("number out of range\n");
}
else if (long_var > INT_MAX)
{
printf("%ld too large!\n", long_var);
}
else if (long_var < INT_MIN)
{
printf("%ld too small!\n", long_var);
}
else if (end_ptr == buff)
{
printf("not valid numeric input\n");
}
/* here is where you might want to add code to */
/* test for extra non-numeric characters at the */
/* end of the input string, if you want that to */
/* be an error */
/* */
/* if you want to generate this error, remove */
/* the two preprocessor lines that start with */
/* #if 0 and #endif */
#if 0
else if ('\0' != *end_ptr)
{
printf("extra characters on input line\n");
}
#endif
else
{
int_var = (int)long_var;
printf("The number %d is OK!\n", int_var);
}
}
return 0;
}
>how about looking up the function atoi ?
atoi is far from crashproof. It results in undefined behavior if anything untoward happens, better to use strtol and cast to an int.