在C语言中读取一个正数

4
我正在尝试找到在C语言中读取正整数的最有效方法。我不能仅使用scanf("%u", &var),因为scanf会对负数取二进制补码,从而破坏这个数字。我也不想手动将字符读入缓冲区,因为这需要我提前知道最大位数,而实际上我只希望受到UINT_MAX的限制。
有什么建议或者我可能忽略的东西吗?

1
你能举一个失败的例子吗? - Andreas Brinck
使用scanf("%u", &var)并输入-1,var将被设置为二进制补码值,但无法区分输入一个如此大的数字和输入-1之间的差别。 - Adam M-W
最大十进制位数并不难猜测:32位值为10位;64位为20位;128位为39位;256位为78位。只需使用“static char buf[MAX_DECIMAL_DIGITS_64BIT + 1]”即可。 - pmg
2个回答

4
也许是这样的:

可能是这样的:

char sign = getchar();
if ('-' == sign) {
    //error
} else {
    ungetchar(sign);
    scanf("%u", &var) 
}

i) 它将失败,并返回“-1”。 ii) 我只有一个可用的ungetc(sign, stdin)函数。 - user786653
在我看来,这有点像是一个黑客方式,但似乎起作用了。最终我做了如下修改: char ch; while ((ch = getc(stdin)) == ' ' || ch == '\f' || ch == '\t' || ch == '\v' || ch == '\n' || ch == '\r'); if (ch != '-'){ungetc(ch, stdin);scanf("%u", &var);} 以确保空格不会引起问题。 - Adam M-W
@Adam:为什么不用while (isspace(ch = fgetc(stdin)));?这个处理的字符和你代码中一样,还可以处理“奇怪”的语言环境中可用的其他内容,而且更容易看。 - pmg
如果输入十六进制或八进制怎么办?最好在上述代码的else部分使用标准库提供的strtoul()功能。请查看以下网址以了解如何操作,注意这是针对strtol的链接 - cyber_raj

0

关于从用户读取一个有符号整数,如果它是负数,则向用户显示错误信息:

int var;
scanf("%d", &var);

if (var < 0) {
    printf("Error: %d is negative", var);
}
else {
    /* use the positive number */
    unsigned int positive = var;
    /* ... */
}

3
这个解决方案的“问题”是你会失去一半无符号整数的范围。 - Andreas Brinck
这是正确的,但用户输入无效(在本例中为负数)的可能性始终存在。必须正确地识别和处理此情况。为了实现这一点,我们必须承担失去一半数字范围的缺点。一种可能性是将输入解析为“长整型”,在某些系统上具有更广泛的范围。 - Constantinius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接