我正在尝试将数字字符串输入转换为整数。当我输入2时,我的输出是0
scanf( "%d", betNumber );
printf("What number do you want to bet? \n");
printf("Here is your number: %d\n" ,atoi(betNumber));
用户输入= 2或3或5 输出=始终为0
答案 0 :(得分:4)
您永远不应该使用*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 number\n", stderr);
return 1;
}
printf("Here is your number: %lu\n", bet);
return 0;
}
一些说明,也许是:
在C中读取用户输入的唯一理智方法是一次整行。如果你不这样做,你很可能会遇到麻烦,而不是用户输入的输入数量超出预期。执行此操作的理想方法是使用getline
,但许多C库没有它,它确实让您记住释放行缓冲区。如果不这样做,fgets
对于许多目的来说已经足够了,如下所示。
在C语言中将文本转换为机器号的唯一正确方法是使用strto*
系列函数。我故意使用正确这个词。所有替代方案都默默地忽略数字溢出(ato*
),或者更糟糕的是,在数字溢出(*scanf
)上触发未定义的行为。 strto*
的使用模式有点棘手,但是一旦你习惯它,它只是记忆和输入的样板。我会把它分开给你:
errno = 0;
在调用errno
之前,有必要手动清除strto*
,因为通过设置{{1}仅报告 的语法有效数字溢出返回值的范围但是,成功不清除errno
。 (该联机帮助页指出返回了一个特定的数值,但该值可能来自正确的输入,因此没有帮助。)
errno
当此函数调用返回时,bet = strtoul(inbuf, &endp, 10);
将是您想要的数字,bet
将被设置为endp
中不是数字的第一个字符。
inbuf
如果if (endp == inbuf || *endp != '\n' || errno) { /* error */ }
等于endp
,则表示没有数字,这通常不被视为有效数字。
如果inbuf
不等于*endp
,则表示 在数字或 {{之后的行上还有其他内容1}}没有看完整行;在任何一种情况下,输入都不是预期的。 (所有64位无符号数都少于80个字符。)
如果'\n'
非零,则发生数字溢出。
答案 1 :(得分:2)
我建议你不要使用scanf
,也不要使用其中任何一个声名狼借的臭名昭着的小伙伴。使用strtol。更容易理解并且不易出错。 atoi是一个不太安全的strtol。
但是... atoi接受了一个指向char的指针。所以如果这个编译......
printf("Here is your number: %d\n" ,atoi(betNumber));
...然后betNumber必须是:
char betNumber[100];
......或类似的东西。这解释了对scanf的调用有什么问题。
scanf(“%d”,p)期望您将传递指向int的指针,而不是指向char的指针。它从标准输入读取文本,将其转换为整数,并将其分配给int变量 - 或者假定必须一个int变量 - 指针指向的变量。那里没有类型检查,不可能。编译器不能告诉你传递了错误的东西(可以编写一个C编译器来验证scanf对格式字符串的参数,但C编译器的一般倾向一直是礼貌地让你自己在脚下射击(modulo gcc) - 墙,谢谢@Zack),这是正确的。
答案 2 :(得分:0)
如果您正确使用scanf()
,例如
int betNumber;
scanf("%d", &betNumber);
然后在scanf()
成功返回后,betNumber
的值已经是整数,您不再需要将其转换。
答案 3 :(得分:0)
scanf和atoi都指向一些先前分配的存储。这是一个有效的例子:
int betNumber;
printf("What number do you want to bet?\n");
scanf("%d", &betNumber);
printf("Here is your number: %d\n", betNumber);