我已经阅读了一段时间的资源,但他们总是在谈论操作时的溢出,但是我如何在用户输入它之前真正检查潜在的 int 溢出,然后才能将其分配给 int 标识符?
我想在输入的那一刻检查输入,这样当发现这样的值已经超出了 int 类型数据的取值范围时,我可以在它进入下一部分代码之前停止它。
最佳答案
你可以读取一个字符串,然后使用 strtol 然后检查 endptr 和 errno,当一切正常时你可以分配你的 整数 变量
详细使用 strtol
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
int main()
{
char s[32]; /* 31 characters is surely large enough for an int */
if (scanf("%31s", s) != 1)
puts("nok");
else {
errno = 0;
char * endptr;
long int l = strtol(s, &endptr, 10);
if (endptr == s)
puts("no digit");
else if ((*endptr != 0) && !isspace(*endptr))
puts("invalid number");
else if (errno != 0)
puts("overflow on long");
else if (((int) l) != l) /* in case long and int do not have the same size */
puts("overflow on int");
else
puts("you enter a valid int");
}
return 0;
}
编译和执行:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra s.c
pi@raspberrypi:/tmp $ ./a.out
a
no digit
pi@raspberrypi:/tmp $ ./a.out
12z
invalid number
pi@raspberrypi:/tmp $ ./a.out
123
you enter a valid int
pi@raspberrypi:/tmp $ ./a.out
12345678901
overflow on long
所以要准确回答这个问题:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
int readInt(int * v)
{
char s[32]; /* 31 characters is surely large enough for an int */
if (scanf("%31s", s) != 1)
return 0;
else {
errno = 0;
char * endptr;
long int l = strtol(s, &endptr, 10);
if ((endptr == s) || /* no digit */
((*endptr != 0) && !isspace(*endptr)) || /* e.g. 12a */
(errno != 0) || /* overflow on long */
(((int) l) != l)) /* overflow on int */
return 0;
*v = (int) l;
return 1;
}
}
int main()
{
int v = 123;
if (readInt(&v))
printf("new valid in value : %d\n", v);
else
printf("unvalid input, still %d\n", v);
return 0;
}
编译和执行:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra s.c
pi@raspberrypi:/tmp $ ./a.out
12
new valid in value : 12
pi@raspberrypi:/tmp $ ./a.out
9878787878787878
unvalid input, still 123
pi@raspberrypi:/tmp $
关于检查输入是否存在可能的 Int 溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54771057/