创建一个atoi函数

4
我试图创建自己的atoi函数。使用以下代码,我得到了一个返回值为0的结果。无论我如何更改函数内部的number变量,我都会得到相应的返回值。有没有修改代码的建议?
//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;
}

1
你使用什么作为输入? - Fred Larson
4
@htor,仅限第一次。 - Carl Norum
1
@KryptNick,你确定这是你的真实代码吗?在我看来它很好,并且在我的测试程序中运行良好。你使用了什么输入? - Carl Norum
1
看起来还好啊。你手头没有调试器吗? - Jonathan Wood
除非您传递的是像“+1234”或“-1234”或“1234”这样的东西(即,领先的字符不是数字) - 您的程序应该正常工作。 您的输入是什么? 粘贴您的函数调用 - 这可能是问题所在。 - user93353
显示剩余12条评论
5个回答

8
  1. You're declaring an array of char *, that is, an array of strings, rather than a single string. You probably want:

    char number[MAXSIZE];
    
  2. Your scanf format string is wrong. If you want to read a string, you should use %s. %c reads only a single character.

  3. Your scanf parameter is wrong - pass number itself (or &number[0] if you prefer), not &number.

  4. The parameter you're passing to atoi_me is wrong. Call it with number (or equivalently &number[0]), not *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需要变量的引用,不是吗? - Ariel Pinchover
@Infested,那我真的不明白。这不就是我的答案吗? - Carl Norum
1
嗯,我不记得写过任何不同的东西。也许我在路上纠正了它。 - Carl Norum
+1,这是被接受的答案,而且它仍然应该是。我并不打算把它拿走。 - jxh
感谢 @user315052。这对我来说无关紧要。 - Carl Norum
显示剩余2条评论

1
正如我所想,问题出在你的调用上。 将你的主函数更改为:
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函数的调用。在Carl Norum指出后现在已经更正了。 - user93353
抱歉...在输入后它无法继续执行函数。它只是崩溃了。 - KryptNick

1
这不是你的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()跳过了数字前面的空格字符。

1
谢谢你的这篇文章。我认为对库函数的深入了解肯定能够避免许多麻烦。 - KryptNick
我并不是想从@CarlNorum那里窃取被接受的答案。这些信息只是对他的回答进行补充。 - jxh

0

一些注释:

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;
}

0

由于 number 应该是char数组,

  • 你应该声明它为char number[MAXSIZE];
  • 你不应该用&number调用你的函数,而应该直接使用numberatoi_me(number);

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