我为什么会使用的atoi(c)中这种出人意料的结果? [英] Why do I get this unexpected result using atoi() in C?

查看:137
本文介绍了我为什么会使用的atoi(c)中这种出人意料的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白下面的C code的结果。

I don't understand the results of the following C code.

main()
{
    char s[] = "AAA";
    advanceString(s);
}

void advanceString(p[3])
{
    int val = atoi(p);
    printf("The atoi val is %d\n",val);
}

下面的的atoi 值显示为0,但我无法找出确切的原因。
按我的理解,它应该是阵列中的每个值的等效十进制数的总和?如果我错了,请大家指正。

Here the atoi value is shown as 0, but I could not figure out the exact reason. As per my understanding, it should be the summation of decimal equivalent of each values in the array? Please correct me if I am wrong.

推荐答案

的atoi() 将字符串转换为重整到它的价值presentation。它不会任意字符转换成十进制值。例如:

atoi() converts a string representation of an integer into its value. It will not convert arbitrary characters into their decimal value. For instance:

int main(void)
{
    const char *string="12345";

    printf("The value of %s is %d\n", string, atoi(string));

    return 0;
}

有什么标准C库,将转换A为65岁或Z90,你需要给自己写的,专门用于任何字符集你希望作为输入。

There's nothing in the standard C library that will convert "A" to 65 or "Z" to 90, you'd need to write that yourself, specifically for whatever charset you're expecting as input.

现在你知道什么的atoi()确实 请不要使用它,以应对数字无论你拿出输入。你真的应该处理输入的不是你所期望的。的嗯,当我输入65,而不是A的该怎么办?的教师爱打破东西。

Now that you know what atoi() does, please don't use it to deal with numeric input in whatever you come up with. You really should deal with input not being what you expect. Hmm, what happens when I enter 65 instead of A? Teachers love to break things.

的atoi()不做任何错误检查无论如何,这使得任何依赖它来任意输入转换脆弱的,最好的。相反,使用 与strtol() (POSIX中心为例):

atoi() doesn't do any error checking whatsoever, which makes anything relying on it to convert arbitrary input fragile, at best. Instead, use strtol() (POSIX centric example):

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(void)
{
    static const char *input ="123abc";
    char *garbage = NULL;
    long value = 0;

    errno = 0;

    value = strtol(input, &garbage, 0);

    switch (errno) {
        case ERANGE:
            printf("The data could not be represented.\n");
            return 1;
        // host-specific (GNU/Linux in my case)
        case EINVAL:
            printf("Unsupported base / radix.\n");
            return 1;
    }

    printf("The value is %ld, leftover garbage in the string is %s\n",
           // Again, host-specific, avoid trying to print NULL.
           value, garbage == NULL ? "N/A" : garbage);

    return 0;
}

在运行,这给:

的值是123,在吃剩的垃圾
  该字符串是ABC

The value is 123, leftover garbage in the string is abc

如果您不关心保存/检查垃圾,你可以设置第二个参数 NULL 。有没有必要免费(垃圾)。还要注意,如果传递0作为第三个参数,它假设输入的是十进制,十六进制或八进制重新presentation的期望值。如果你需要的10为基数,用10 - 它会失败,如果输入的是不是像您期望

If you don't care about saving / examining the garbage, you can set the second argument to NULL. There is no need to free(garbage). Also note, if you pass 0 as the third argument, it's assumed the input is the desired value of a decimal, hex or octal representation. If you need a radix of 10, use 10 - it will fail if the input is not as you expect.

您也想检查最大和长整型可处理最小值的返回值。但是,如果不是返回到指示错误,错误号设置。对于读者的练习就是要改变 *输入 123ABC ABC123

You'd also check the return value for the maximum and minimum value a long int can handle. However, if either are returned to indicate an error, errno is set. An exercise for the reader is to change *input from 123abc to abc123.

检查返回,作为你的例子显示了如果不这样做会发生什么是很重要的。 ABCDEFG是不是再一个整数presentation一个字符串,你需要处理,在你的函数。

It's important to check the return, as your example shows what happens if you don't. AbcDeFg is not a string representation of an integer, and you need to deal with that in your function.

有关您的实现,最基本的意见,我可以给你将是一个系列交换机的,是这样的:

For your implementation, the most basic advice I can give you would be a series of switches, something like:

// signed, since a return value of 0 is acceptable (NULL), -1
// means failure
int ascii_to_ascii_val(const char *in)
{
    switch(in) {
        // 64 other cases before 'A'
        case 'A':
           return 65;
        // keep going from here
        default:
            return -1; // failure

}

..然后只需运行在一个循环。

.. then just run that in a loop.

或者,pre-填充字典,查找功能,可以范围(更好)。您不需要散列,只是一个键 - > value存储,因为你知道它会提前,其中标准的ASCII字符是键遏制,以及它们相应的标识符的值。

Or, pre-populate a dictionary that a lookup function could scope (better). You wouldn't need hashes, just a key -> value store since you know what it's going to contain in advance, where the standard ASCII characters are keys, and their corresponding identifiers are values.

这篇关于我为什么会使用的atoi(c)中这种出人意料的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆