我想从stdin读取一个int,但我想验证用户是否超过了int max值。我该怎么办?
int n;
scanf("%d", &n);
scanf读取十进制输入并存储在int中,导致溢出。我该如何检查并避免这种情况?
答案 0 :(得分:13)
将数字的字符串表示形式转换为实际值并注意溢出的唯一方法是使用strto..
组中的函数。在您的情况下,您需要读取数字的字符串表示,然后使用strtol
函数进行转换。
请注意建议使用atoi
或sscanf
执行最终转化的回复。这些功能都不能防止溢出。
答案 1 :(得分:3)
另一种方法是将最大数字设置为解析。
例如:
int n;
scanf("%5d", &n); // read at most 5 digits
printf("%i\n", n);
答案 2 :(得分:0)
我想到了两种方法。
如果你知道输入只是类似整数的输入,那么第一个是有用的,但是稍微有点"#34;超过整数范围:
long x;
if (1 != scanf("%ld", &x))
error "not a number or other i/o error"
else
if (x < -MAXINT || x > MAXINT)
error "exceeds integer range"
else printf "it is an integer";
这对编译器和平台有很多依赖性。请注意,C语言仅保证long
大于或等于大小为int
。如果这是在long
和int
大小相同的平台上运行,那么这是一种无用的方法。
第二种方法是将输入作为字符串读取并直接解析:
char buf [1000];
if (1 != scanf ("%1000s", buf))
error "i/o error";
size_t len = strspn (buf, "0123456789+-");
if (len != strlen (buf))
error "contains invalid characters";
long number = 0;
int sign = 1;
for (char *bp = buf; *bp; ++bp)
{
if (*bp == '-')
{
sign = -sign;
continue;
}
if (*bp == '+')
continue;
number = number * 10 + *bp - '0';
if (number > MAXINT)
error "number too large";
}
if (sign < 0)
number = -number;
此代码有几个缺点:它取决于long
大于int
;它允许加号和减号出现在字符串中的任何位置。它可以很容易地扩展到允许十个以外的数字。
可能的第三种方法可能是输入字符串检查字符集并使用double
转换进行范围检查。
答案 3 :(得分:-1)
将其读入字符串并检查长度,然后调用字符串上的atol()
或sscanf()
将其转换为int。