40

I want to convert a char array[] like:

char myarray[4] = {'-','1','2','3'}; //where the - means it is negative

So it should be the integer: -1234 using standard libaries in C. I could not find any elegant way to do that.

I can append the '\0' for sure.

4

5 回答 5

88

我个人不喜欢atoi功能。我建议sscanf

char myarray[5] = {'-', '1', '2', '3', '\0'};
int i;
sscanf(myarray, "%d", &i);

这是非常标准的,它在stdio.h图书馆里:)

而且在我看来,它比数字字符串的任意格式提供了更多的自由atoi,并且可能还允许在末尾使用非数字字符。

编辑 我刚刚在网站上发现了这个奇妙的问题,它解释和比较了 3 种不同的方法 -atoi和。此外,对(实际上是整个函数系列)有一个很好的更详细的见解。sscanfstrtolsscanf*scanf

EDIT2 看起来不仅仅是我个人不喜欢这个atoi功能。这是一个答案的链接,解释该atoi函数已被弃用,不应在较新的代码中使用。

于 2012-04-18T07:14:34.530 回答
12

为什么不只使用atoi?例如:

char myarray[4] = {'-','1','2','3'};

int i = atoi(myarray);

printf("%d\n", i);

正如预期的那样给了我:

-123

更新:为什么不 - 字符数组不是以空值结尾的。嗬!

于 2012-04-18T07:07:18.120 回答
3

在不将数组转换为字符串的情况下处理字符数组本身并不难。特别是在字符数组的长度已知或很容易找到的情况下。对于字符数组,长度必须在与数组定义相同的范围内确定,例如:

size_t len sizeof myarray/sizeof *myarray;

当然,对于您可以使用的字符串strlen

在已知长度的情况下,无论是字符数组还是字符串,都可以通过类似下面的short函数将字符值转换为数字:

/* convert character array to integer */
int char2int (char *array, size_t n)
{    
    int number = 0;
    int mult = 1;

    n = (int)n < 0 ? -n : n;       /* quick absolute value check  */

    /* for each character in array */
    while (n--)
    {
        /* if not digit or '-', check if number > 0, break or continue */
        if ((array[n] < '0' || array[n] > '9') && array[n] != '-') {
            if (number)
                break;
            else
                continue;
        }

        if (array[n] == '-') {      /* if '-' if number, negate, break */
            if (number) {
                number = -number;
                break;
            }
        }
        else {                      /* convert digit to numeric value   */
            number += (array[n] - '0') * mult;
            mult *= 10;
        }
    }

    return number;
}

以上只是标准的 char 到 int 的转换方法,包括一些额外的条件。要处理杂散字符,除了digitsand之外'-',唯一的技巧是明智地选择何时开始收集数字以及何时停止。

如果您digits在遇到第一个时开始收集转换digit,则在遇到第一个'-'或时转换结束non-digit。当对(例如file_0127.txt)等索引感兴趣时,这使得转换更加方便。

一个简短的使用示例:

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

int char2int (char *array, size_t n);

int main (void) {

    char myarray[4] = {'-','1','2','3'}; 
    char *string = "some-goofy-string-with-123-inside";
    char *fname = "file-0123.txt";

    size_t mlen = sizeof myarray/sizeof *myarray;
    size_t slen = strlen (string);
    size_t flen = strlen (fname);

    printf ("\n myarray[4] = {'-','1','2','3'};\n\n");
    printf ("   char2int (myarray, mlen):  %d\n\n", char2int (myarray, mlen));

    printf (" string = \"some-goofy-string-with-123-inside\";\n\n");
    printf ("   char2int (string, slen) :  %d\n\n", char2int (string, slen));

    printf (" fname = \"file-0123.txt\";\n\n");
    printf ("   char2int (fname, flen)  :  %d\n\n", char2int (fname, flen));

    return 0;
}

注意:当遇到'-'分隔的文件索引(或类似的)时,您可以否定结果。(例如,file-0123.txtfile_0123.txt第一个将返回-123而第二个返回的位置相比123)。

示例输出

$ ./bin/atoic_array

 myarray[4] = {'-','1','2','3'};

   char2int (myarray, mlen):  -123

 string = "some-goofy-string-with-123-inside";

   char2int (string, slen) :  -123

 fname = "file-0123.txt";

   char2int (fname, flen)  :  -123

注意:总是存在可能导致问题的极端情况等。这并不是为了在所有字符集等中都 100% 防弹,而是在绝大多数时间工作并提供额外的转换灵活性,而无需初始解析或转换为atoiorstrtol等​​所需的字符串。

于 2015-05-23T22:05:55.057 回答
2

所以,这个想法是将字符数字(在单引号中,例如'8')转换为整数表达式。例如 char c = '8'; int i = c - '0' //将产生整数 8; 并按照908=9*100+0*10+8的原则将所有转换后的数字相加,循环完成。

char t[5] = {'-', '9', '0', '8', '\0'}; //Should be terminated properly.

int s = 1;
int i = -1;
int res = 0;

if (c[0] == '-') {
  s = -1;
  i = 0;
}

while (c[++i] != '\0') { //iterate until the array end
  res = res*10 + (c[i] - '0'); //generating the integer according to read parsed numbers.
}

res = res*s; //answer: -908
于 2015-05-23T15:46:13.763 回答
0

这不是问题所要问的,但我使用了@Rich Drummond 的答案来处理从标准输入读取的以空值结尾的字符数组。

char *buff;
size_t buff_size = 100;
int choice;
do{
    buff = (char *)malloc(buff_size *sizeof(char));
    getline(&buff, &buff_size, stdin);
    choice = atoi(buff);
    free(buff);
                    
}while((choice<1)&&(choice>9));
于 2020-07-02T20:57:57.010 回答