在C语言中将字符数字转换为相应的整数

138

在C语言中,有一种方法可以将字符转换为整数。

例如,从'5'到5?

14个回答

199

根据其他回复,这是可以的:

char c = '5';
int x = c - '0';

另外,为了进行错误检查,您可能希望首先检查isdigit(c)返回true。请注意,对于字母,您无法完全可移植地执行相同的操作,例如:

char c = 'b';
int x = c - 'a'; // x is now not necessarily 1

标准保证数字 '0' 到 '9' 的 char 值是连续的,但对于字母等其他字符没有任何保证。


3
是的,针对数字而不是字母,因为正如我在答案中所说,标准保证 '0' 到 '9' 是连续的,但并不保证其他字符如 'a' 到 'z' 也是连续的。 - Chris Young
char c = 'b'; int x = c - 'a'; 那么在ASCII码中,x将只是1吗? - dsfdf
@Pan 在任何编码中,包括ASCII,都有'b'比'a'多1。在EBCDIC中仍然成立,但是('j' - 'i') == 8。 - Chris Young
@ChrisYoung 为什么?因为在EBCDIC中,'j'并不比'i'大1。 - dsfdf
2
我在这里缺少什么,没有使用atoi函数? - Daniel

51

像这样减去'0':

int i = c - '0';

C标准保证了在范围'0'..'9'内的每个数字都比它前面的数字大1(详见C99 draft的5.2.1/3节)。C++同样适用。

2
如果您提到char已经是一个整数(虽然其符号由实现定义,即可能是有符号或无符号的),并且其长度为CHAR_BITS,那么这个答案会更好。 - Arafangion
我不确定知道那个是否真的对他有帮助。但是Chris提出了一个很好的观点,即a到z不一定是连续的。我应该提到这一点。现在他赢得了比赛 :) - Johannes Schaub - litb
1
你的答案更好,因为你做了限定,克里斯也有可能是胡编乱造的。 :) - Arafangion
感谢您的赞赏。我承认我对C语言的状态不太确定,所以我查了一下资料,因为我已经在做这个了,所以我把参考资料粘贴到了答案中 :) - Johannes Schaub - litb
先生,这就是为什么您比我多几个点的原因。 :) - Arafangion
我相信你,伙计。我也常常在回答问题时没有贴上标准部分的参考资料。但这一次,在回答后我查看了相关章节,并掌握了章节号码,所以很容易就改变了我的回答并添加了标准部分的引用 :) 干杯 - Johannes Schaub - litb

37

如果出现一种疯狂的巧合,你需要将一个字符串转换为整数,你也可以做到!

char *num = "1024";
int val = atoi(num); // atoi = ASCII TO Int

val 现在是 1024。显然 atoi() 很好用,我之前说的只适用于我自己(在 OS X 上(也许(在这里插入 Lisp 笑话)))。我听说它是一个宏,大致映射到下面的示例,该示例使用更通用的函数 strtol() 来执行转换:

char *num = "1024";
int val = (int)strtol(num, (char **)NULL, 10); // strtol = STRing TO Long

strtol() 的工作原理如下:

long strtol(const char *str, char **endptr, int base);

这个函数将*str转换成一个long类型的数值,把它当做一个以base为底的数字来处理。如果**endptr不是空指针,它会保存strtol()找到的第一个非数字字符(但是谁在乎呢)。


atoi没有线程问题(它没有静态数据),也没有被弃用。实际上,它在功能上等同于:#define atoi(x) (int)(strtol((x), NULL, 10) - Evan Teran
5
atoi存在的问题是它将0作为“无法找到数字”的值,因此atoi("0")和atoi("one")都返回0。如果这对你使用不起作用,可以尝试使用strtol()或sscanf()。 - David Thornley
当然,strtol 的另一个优点是您可能需要从相同的字符串中读取数字后面的其他内容。 - dfeuer
很不幸,如果你运行Visual Studio,你会收到一个弃用警告(并且未被禁用的情况下无法编译)。VS现在推荐使用itoa_s() - Xantium

19

将字符数字转换为相应的整数。请按照以下步骤执行:

char c = '8';                    
int i = c - '0';

以上计算背后的逻辑是玩弄 ASCII 值。字符 8 的 ASCII 值为 56,字符 0 的 ASCII 值为 48。整数 8 的 ASCII 值为 8。

如果我们减去两个字符,减法将在字符的 ASCII 值之间进行。

int i = 56 - 48;   
i = 8;

2
为什么只有我点赞了这个?解释如此简单明了 :+1: - Brandon Benefield
谢谢,这个解释涵盖了一个查看C的属性的人可能无法将其与ASCII联系起来的事实。我直接从K&R过来,他们在这个问题上有点草率。 - Quincy Tennyson

14

像这样减去字符 '0' 或整数 48 :

char c = '5';
int i = c - '0';

说明:它在内部使用ASCII值进行计算。 根据ASCII表,字符5的十进制值为53,而0的十进制值为48。 因此,53-48 = 5

或者

char c = '5';
int i = c - 48; // Because decimal value of char '0' is 48

这意味着,如果您从任何数字字符中减去48,它将自动转换为整数。


6
char numeralChar = '4';
int numeral = (int) (numeralChar - '0');

numeralChar - '0' 已经是 int 类型,因此您不需要进行强制转换。即使它不是,也不需要进行强制转换。 - Alok Singhal
哦,是的,那会强制转换吧?也许是因为我用Java太多了。或者我完全弄错了,它甚至在Java中也会强制转换。 :) - easeout

2

以下是几个辅助函数,可以将字符中的数字转换为整数,也可以将整数转换为字符:

Original Answer翻译成"最初的回答"

int toInt(char c) {
    return c - '0';
}

char toChar(int i) {
    return i + '0';
}

1
只需使用 atol() 函数:
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    const char *c = "5";
    int d = atol(c);
    printf("%d\n", d);

}

1
如果你的数字是,比如说,'5',在ASCII中它被表示为二进制数0011 0101(53)。每个数字都有最高的四位0011,最低的4位表示BCD码中的数字。所以你只需要执行
char cdig = '5';
int dig = cdig & 0xf; // dig contains the number 5

获取最低的4个比特位,或者说,就是数字。在汇编语言中,它使用and操作而不是sub(如其他回答中所示)。


“'5'” 是 53(00110101 - eyllanesc
@eyllanesc 起初它是4。谢谢。我已经编辑了它。 - Garmekain

0

请检查此内容,

char s='A';

int i = (s<='9')?(s-'0'):(s<='F')?((s-'A')+10):((s-'a')+10);

对于仅为0、1、2、....、E、F的情况。


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