我想要将一个char数组[]转换为:
char myarray[4] = {'-','1','2','3'}; //where the - means it is negative
在C语言的标准库中,应该是这个整数:-1234。我找不到任何优雅的方法来实现它。
我可以肯定地添加'\0'。
我个人不太喜欢使用atoi
函数。我建议使用sscanf
函数:
char myarray[5] = {'-', '1', '2', '3', '\0'};
int i;
sscanf(myarray, "%d", &i);
非常标准,它在stdio.h
库中 :)
而且在我看来,与 atoi
相比,它允许您更多的自由度,可以任意格式化数字字符串,并且可能还允许在末尾加入非数字字符。
编辑
我刚刚在这个网站上找到了一个精彩的问题,它解释并比较了3种不同的方法 - atoi
、sscanf
和 strtol
。此外,还有一个关于sscanf
(实际上是整个*scanf
函数族)的详细见解。
编辑2
看起来并不只是我个人不喜欢atoi
函数。这里有一个链接,其中解释了atoi
函数已被弃用,不应在新代码中使用。
sscanf
如何解析 %d
?它调用了 atoi
,所以无论如何都是杀鸡焉用牛刀。 - Eregrithatoi
的原因是它会默默失败。虽然没有静态缓冲区会导致线程安全问题,但在这里使用strtol
确实是正确的函数。 - Ben Voigt为什么不直接使用 atoi 呢?例如:
char myarray[4] = {'-','1','2','3'};
int i = atoi(myarray);
printf("%d\n", i);
给出了我期望的结果:-123
更新:为什么不行-字符数组没有以空字符结尾。天啊!
不需要把字符数组转换为字符串,直接处理字符数组本身并不难,特别是在已知字符数组长度或可以轻易获取的情况下。使用字符数组时,必须在与数组定义相同的作用域中确定其长度,例如:
size_t len sizeof myarray/sizeof *myarray;
当涉及到字符串时,你当然可以使用strlen
函数来计算长度。
一旦确定了长度,无论是字符数组还是字符串,你都可以使用下面类似的简短函数将字符值转换为数字:
/* 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;
}
#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.txt
与file_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
注意: 总会有一些特殊情况等问题可能导致程序出现错误。本方法无法在所有字符集中都百分之百地保证有效,但通常情况下可以解决大多数问题,并且可以提供更高的转换灵活性,而不需要像 atoi
或 strtol
那样需要进行初始解析或字符串转换。因此,这个想法是将字符数字(用单引号表示,例如'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
'\0'
,最好使用标准库(请参见其他答案)。如果你无法获得终止NUL字节(循环条件已更改),则可以使用此方法。 - hyde这不是问题所问的,但我使用了 @Rich Drummond 的答案来从 stdin 中读取一个以 null 结尾的 char 数组。
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));
4
'\0'
添加到数组末尾的可能性吗?那样我们就不用花太多时间了。 - Mr Listeratoi
和strtol
是其中的两个选项。例如:char myarray[] = {'-','1','2','3','4',0}; int i = atoi(myarray);
- falstro'\0'
,让编译器自己来处理:char myarray[] = "-1234";
- Jerry Coffin