【问题标题】:Creating an atoi function创建 atoi 函数
【发布时间】:2013-04-17 17:56:40
【问题描述】:

我正在尝试创建自己的 atoi 函数。使用以下内容,我得到的返回值为 0。无论我更改函数中的数字变量,我得到的都是返回值。关于修改代码的任何建议?

//my atoi function
int atoi_me(char *numstring)
{
    int number = 0;
    while((*numstring >= '0') && (*numstring <= '9'))
    {
        number = (number * 10) + (*numstring - '0');
        numstring++;
    }

    return number;
}

int main()
{
    char *number[MAXSIZE];
    int num;

    printf("Please enter a number:\n");
    scanf("%c", &number);
    num = atoi_me(*number);
    printf("%d", num);
    return 0;
}

【问题讨论】:

  • 你使用什么作为输入?
  • 表达式number = (number * 10) 将始终为0
  • @htor,只是第一次。
  • @KryptNick,你确定这是你的真实代码吗?它对我来说看起来不错,并且在这里的测试程序中运行良好。你用的是什么输入法?
  • 我觉得没问题。你手边没有调试器吗?

标签: c function atoi


【解决方案1】:
  1. 您正在声明一个char * 数组,即字符串数组,而不是单个字符串。你可能想要:

    char number[MAXSIZE];
    
  2. 您的scanf 格式字符串错误。如果你想读取一个字符串,你应该使用%s%c 只读取一个字符。

  3. 您的 scanf 参数错误 - 传递 number 本身(或 &amp;number[0],如果您愿意),而不是 &amp;number

  4. 您传递给atoi_me 的参数错误。用number(或等效的&amp;number[0])调用它,而不是*number

将所有这些放在一起,您应该有一个类似这样的main 例程:

int main(void)
{
    char number[MAXSIZE];
    int num;
    printf("Please enter a number: ");
    scanf("%s", number);
    num = atoi_me(number);
    printf("%d\n", num);
    return 0;
} 

编者注:scanf 行可能导致缓冲区溢出。您最好使用像 fgets(3) 这样的函数,它可以轻松防止此类问题。

atoi(3) 传统上还支持负数(带有前导 -)和可选的前导 + 用于正数,您的实现无法处理。

【讨论】:

  • 我认为有数字是可以的,因为 scanf 想要一个对变量 no 的引用?
  • @Infested,number 是一个数组,因此在此上下文中使用时会衰减为指向其第一个元素的指针。我不太确定你在问什么。
  • @Infested,那我真的不明白。我的回答是这样说的,不是吗?
  • 嗯,我不记得写了什么不同的东西。也许我在途中的某个地方纠正了它。
  • +1,这是公认的答案,而且应该仍然如此。我不打算把它偷走。
【解决方案2】:

正如我所想,问题出在你的电话上。

将你的主要更改为。

int main()
{
    char number[MAXSIZE];
    int num;

    printf("Please enter a number:\n");
    scanf("%s", number);
    num = atoi_me(number);
    printf("%d", num);
    return 0;
}

除此之外,使用 scanf - http://c-faq.com/stdio/scanfprobs.html 不是一个好主意。在这种情况下,您应该使用fgets

【讨论】:

  • @KryptNick - 你是什么意思'锁定。无论如何,我错过了更改 atoi_me 电话。在卡尔·诺鲁姆指出之后现在改变了它。
  • 对不起...输入后它不会继续进入函数。它只是崩溃了
【解决方案3】:

这不是您的atoi_me() 函数的问题,而是您获取输入的方式的问题。您的实现表明您对scanf() 工作原理的理解存在一些弱点。这本身不是问题,犯错毕竟是学习过程的一部分。

首先将您的输入收集到缓冲区通常更安全,因为来自标准输入的scanf() 过于依赖程序用户来完全按照您期望的方式输入输入。在这种情况下,没有太大的危害,因为您只需要一行输入。但是,通常,一个程序会处理多行输入,而scanf() 可能会在发生错误时卡住。因此,您可以使用类似这样的方法来获取您的输入行:

char line[MAXLINESIZE];

if (fgets(line, MAXLINESIZE, stdin) == 0) {
    fprintf(stderr, "no input was provided!\n");
    return 0;
}

正如在其他地方提到的,%c 是用于您收集的输入的错误格式说明符。由于您需要十进制数字,*scanf() 系列有一个格式说明符,允许您只收集这些字符。

char number[MAXSIZE];

if (sscanf(line, " %[0-9]", number) != 1) {
    fprintf(stderr, "no number found in input: %s", line);
    return 0;
}

在这里,我使用通过fgets() 检索到的line,并解析出包含数字的输入部分。前导空格导致sscanf() 跳过导致数字的空格字符。

【讨论】:

  • 感谢这篇文章。我看到对库函数的深入了解绝对可以省去头疼的问题。
  • 我并不是想从@CarlNorum 那里窃取已接受的答案。此信息是对他的回答的补充。
【解决方案4】:

由于number 应该是一个字符数组,

  • 您应该将其声明为char number[MAXSIZE];
  • 你不应该用&amp;number调用你的函数,而是用number,直接:atoi_me(number);

【讨论】:

    【解决方案5】:

    一些cmets:

    int atoi_me(const char *numstring)...
    

    最好使用 const 类型指针,因为您不打算修改字符串内容。

    int main()
    {
        char number[MAXSIZE]; // array of chars
        int num;
    
        printf("Please enter a number:\n");
        scanf("%s", number);     // enter a string, not a char
        num = atoi_me(number);   // pointer to char, not pointer to pointer
        printf("%d", num);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-11-07
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多