我从用户输入中得到很长时间(使用fgets()
并使用strtoul()
转换为long),但在测试时将其转换为整数会产生错误结果。
声明:
char buf[BUFSIZE];
unsigned char input[80];
int done = 0;
int i, val;
long valPrimary;
char *ptr;
代码:
// gets the max first 79 characters, whichever comes first
if (fgets(input, INPUTSIZE, stdin) != NULL) {
printf("Input ok\n");
} else {
printf("Input not ok\n");
return 0;
}
// get unsigned long from input
valPrimary = strtoul(input, &ptr, 10);
// Check if any character was converted
if (ptr == input) {
fprintf(stderr, "Can't convert string to number\n");
return 0;
}
if ((valPrimary == LONG_MAX || valPrimary == LONG_MIN) && errno== ERANGE) {
fprintf(stderr, "Number out of range for LONG\n");
return 0;
}
printf("valPrimary: %lu\n", valPrimary);
printf("Max Int: %i\n", INT_MAX);
printf("Min Int: %i\n", INT_MIN);
printf("Long size: %lu\n", sizeof(long));
// Check overflows and if long is convertable to int
if ( (valPrimary > INT_MAX) || (valPrimary < INT_MIN) ) {
fprintf(stderr, "Number out of range for INT\n");
return 0;
} else {
val = (int) valPrimary;
}
例如,如果我输入一个非常大的数字,我会得到这种标准输出:
valPrimary:18446744073709551615
Max Int:2147483647
但不会显示错误消息,转换仍然会发生。
答案 0 :(得分:1)
signed long
和strtoul()
混音不正确。使用strtol()
。 @Quentin
strtoul("18446744073709551615",...)
- &gt; ULONG_MAX
转换为long
的{{1}}可能会变为-1
。
long valPrimary;
...
// valPrimary = strtoul(input, &ptr, 10);
valPrimary = strtol(input, &ptr, 10);
...
if ((valPrimary == LONG_MAX || valPrimary == LONG_MIN) && errno== ERANGE) {
fprintf(stderr, "Number out of range for LONG\n");
答案 1 :(得分:1)
可能发生的事情是:
valPrimary声明为:
Thread
而不是:
pm.getState()
十进制值long valPrimary;
对应十六进制值unsigned long valPrimary
。
当该值存储在有符号长整数中时,第一位是符号位。实际上,签名长中的18446744073709551615
等于0xffffffffffffffff
。
Hece,转换完成后,返回0xffffffffffffffff
,因为INT_MAX&gt; -1&gt; INT_MIN