I'm relatively new to C and would like to know how to prevent an overflow from input...
So for example, I have:
scanf("%d", &a);
Where a is an integer.
So what I could I do to prevent someone from entering a number that's larger than max integer? Due to the constraints of the problem I'm working on, you HAVE to use scanf
. How do I go about restricting the input?
Thanks in advance.
'Tis very challenging to prevent user input.
There is no magic hand to reach out and stop the user from beating away at the keyboard.
But code can limit what it reads.
1) scanf()
is tough to limit. It may not set errno
on overflow. Code can limit the number of char
to say 9. That's a first step but one can not enter values like "1000000000" or "00000000000000001".
// Assume INT_MAX = 2,147,483,647.
scanf("%9d", &a);
2) A pedantic method would use fgetc()
. An unsigned
method follows. int
takes a bit more.
unsigned a = 0;
int ch = fgetc(stdin);
while (isspace(ch)) {
ch = fgetc(stdin);
}
while (isdigit(ch)) {
unsigned newa = a*10 + ch - '0';
if (newa < a) {
break; // overflow detected.
}
a = newa;
ch = fgetc(stdin);
}
ungetc(ch, stdin); // Put back `ch` as it was not used.
3) But I prefer to change the goal and simply tell the user again, even if it mean reading in more characters.
// 0:success or EOF
int Read_int(const char *prompt, int *dest, int min, int max) {
for (;;) {
char buf[sizeof(int)*3 + 3];
fputs(prompt, stdout);
if (fgets(buf, sizeof buf, stdin) == NULL) {
return EOF;
}
char *endptr;
errno = 0;
long l = strtol(buf, &endptr, 10);
if (buf == endptr || *endptr != '\n') {
continue; // only \n entered or invalid `chars` entered
}
if (!errno && l >= min && l <= max) {
*dest = (int) l;
return 0; // success
}
}
}
int a;
Read_int("Enter an `int`\n", &a, INT_MIN, INT_MAX);