将输入数字字符串转换为C中的整数

时间:2014-04-10 17:26:06

标签: c string integer

我正在尝试将数字字符串输入转换为整数。当我输入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

4 个答案:

答案 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);