我正在尝试将数字字符串输入转换为整数。当我键入2时,我的输出为0
scanf( "%d", betNumber );
printf("What number do you want to bet? n");
printf("Here is your number: %dn" ,atoi(betNumber));
用户输入=2或3或5输出=始终为0
您永远不应该使用*scanf
家族,也不应该使用atoi
和朋友。编写此代码的正确方法是
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(void)
{
char inbuf[80], *endp;
unsigned long bet; /* negative bets don't make sense */
puts("What number do you want to bet?");
if (!fgets(inbuf, sizeof inbuf, stdin))
return 1; /* EOF - just quit */
errno = 0;
bet = strtoul(inbuf, &endp, 10);
if (endp == inbuf || *endp != 'n' || errno) {
fputs("invalid number entered, or junk after numbern", stderr);
return 1;
}
printf("Here is your number: %lun", bet);
return 0;
}
也许是一些阐述:
在C中读取用户输入的唯一合理方法是一次一整行。如果你不这样做,当用户键入的输入比你预期的多时,你很可能会遇到麻烦。实现这一点的理想方法是使用getline
,但许多C库没有它,而且它确实让您记住释放行缓冲区。如果做不到这一点,fgets
在许多方面都足够好,如下所示。
将文本转换为C中的机器编号的唯一正确方法是使用strto*
函数族。我非常刻意地使用这个词来纠正。所有备选方案要么默默忽略数字溢出(ato*
),要么更糟的是,触发数字溢出上的未定义行为(*scanf
)。strto*
的使用模式有点棘手,但一旦你习惯了它,它就只是记忆和键入的样板。我帮你拆开:
errno = 0;
在调用strto*
之前,有必要手动清除errno
,因为通过设置errno
,溢出返回值范围的语法有效数字只报告,但成功不清除errno
。(手册页上说,会返回一个特定的数值,但该值可能是由正确的输入产生的,所以这没有帮助。)
bet = strtoul(inbuf, &endp, 10);
当此函数调用返回时,bet
将是您想要的数字,而endp
将被设置为inbuf
中第一个不是数字的字符。
if (endp == inbuf || *endp != 'n' || errno) { /* error */ }
如果endp
等于inbuf
,则意味着没有数字,这通常不被视为有效数字。
如果*endp
不等于'n'
,这意味着或者数字后面的行上有其他东西,或fgets
没有读取整行;在任何一种情况下,输入都不是预期的。(所有64位无符号数字可容纳少于80个字符。)
如果errno
为非零,则发生数字溢出。
我建议你不要使用scanf
,也不要使用它的任何臭名昭著的阴险伙伴。使用strtol。更容易让你的头脑清醒,而且不容易出错。atoi是一种不太安全的strtol等价物。
但是。。。atoi将指针指向char。所以如果这个编译。。。
printf("Here is your number: %dn" ,atoi(betNumber));
则betNumber必须为:
char betNumber[100];
或者类似的东西。这就解释了调用scanf的错误。
scanf("%d",p)预期您将向它传递一个指向int的指针,而不是指向char的指针。它从标准输入中读取文本,将其转换为整数,并将其分配给指针所指向的int变量——或者它认为必须是的int变量。那里没有类型检查,不可能有。编译器无法判断您传递了错误的东西(可以编写C编译器来验证scanf针对格式字符串的参数,但C编译器的普遍趋势一直是礼貌地让您开枪自杀(modulo-gcc-Wall,谢谢@Zack),这是正确的)。
如果正确使用scanf()
,例如
int betNumber;
scanf("%d", &betNumber);
那么scanf()
返回成功后,betNumber
的值已经是一个整数,不需要再进行转换。
scanf和atoi都使用一个指针指向以前分配的一些存储。下面是一个工作示例:
int betNumber;
printf("What number do you want to bet?n");
scanf("%d", &betNumber);
printf("Here is your number: %dn", betNumber);