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


103

有没有办法将字符转换为C中的整数?

例如,从'5'到5?

Answers:


147

根据其他答复,这很好:

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

另外,对于错误检查,您可能希望先检查isdigit(c)是否为真。请注意,您不能完全便携地对字母执行相同的操作,例如:

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

该标准保证数字'0'至'9'的char值是连续的,但不保证其他字符(如字母)。


3
@Paul Tomblin:是的,不是数字,而是字母,因为正如我在回答中所说,标准保证“ 0”至“ 9”是连续的,但对诸如“ a”至“ z”之类的其他字符不作保证。
克里斯·杨

char c ='b'; int x = c-'a'; 那么x仅在ASCII中将为1?
2013年

@Pan在任何编码中,包括ASCII,其'b'比'a'多1。这在EBCDIC中仍然适用,但是它使('j'-'i')==8。–
克里斯·杨

@ChrisYoung为什么?原因在EBCDIC中,“ j”比“ i”大1吗?
2013年

2
我在这里缺少什么不使用atoi的地方?
丹尼尔(Daniel)

41

像这样减去“ 0”:

int i = c - '0';

C标准保证范围内的每个数字'0'..'9'是比其前一个数字(在第一个较大5.2.1/3的的C99草案)。对于C ++同样重要。


1
如果您提到char是/已经/有效地是一个整数,可以使用实现定义的符号(即,可以是有符号的或无符号的),并且长度为CHAR_BITS,则此答案会更好。
Arafangion

我不确定是否真的对他有帮助。但是Chris提出了一个很好的观点,即a..z不一定是连续的。我应该提到它。现在他赢得了比赛:)
约翰内斯·绍布

1
不过,您的水平会更好,因为您已经确定了答案的答案-克里斯很可能已经做好了准备。:)
Arafangion 2009年

感谢您的赞赏。我承认我不确定C的状态,所以我抬起头来,因为我已经在看它了,所以我将引用粘贴到了答案中:)
Johannes Schaub-litb

先生,这就是为什么您的积分比我高出几分的原因。:)
Arafangion 2009年

29

如果出于某种偶然的巧合,想要将字符串转换为整数,也可以这样做!

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

它转换 *strlong,将其视为底数base。如果**endptr不为null,它将保存找到的第一个非数字字符strtol()(但谁在乎这一点)。


atoi没有线程问题(它没有静态数据),因此不建议使用。实际上,它在功能上等效于:#define atoi(x)(int)(strtol((x),NULL,10)
Evan Teran

5
atoi的问题在于它使用0作为“在这里找不到数字”值,因此atoi(“ 0”)和atoi(“ one”)都返回0。如果这对您不起作用,重新使用它,寻找strtol()或sscanf()。
David Thornley,2009年

当然,strtol的另一个优点是您可能需要从数字后的同一字符串中读取其他内容。
dfeuer 2012年

@EvanTeran不幸的是,如果您运行Visual Studio,则会收到折旧警告(并且不会被禁用而不会进行编译)。VS现在推荐itoa_s()
西蒙(Simon)

7

像这样减去char'0'或int 48:

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

说明:它在内部使用ASCII值。从ASCII表,字符的十进制值5是530是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'2

嗯,是的,这是强制性的,不是吗?也许Java改变了我的看法。也许我完全弄错了,它甚至会在Java中强制转换。:)
Kevin Conner 2010年

5

将字符数字转换为相应的整数。如下所示:

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

以上计算的逻辑是使用ASCII值。字符8的ASCII值为56,字符0的ASCII值为48。整数8的ASCII值为8。

如果我们减去两个字符,则字符的ASCII之间将相减。

int i = 56 - 48;   
i = 8;

为什么我是唯一对此表示支持的人?说明是如此简单和
有益

0

如果只是ASCII中的0-9单个字符,则从ASCII值中减去ASCII零字符的值应该可以正常工作。

如果要转换较大的数字,则可以执行以下操作:

char *string = "24";

int value;

int assigned = sscanf(string, "%d", &value);

**不要忘记检查状态(如果在上述情况下有效,则应为1)。

保罗


0
char chVal = '5';
char chIndex;

if ((chVal >= '0') && (chVal <= '9')) {

    chIndex = chVal - '0';
}
else 
if ((chVal >= 'a') && (chVal <= 'z')) {

    chIndex = chVal - 'a';
}
else 
if ((chVal >= 'A') && (chVal <= 'Z')) {

    chIndex = chVal - 'A';
}
else {
    chIndex = -1; // Error value !!!
}

0

当我需要做这样的事情时,我会用所需的值预烘烤一个数组。

const static int lookup[256] = { -1, ..., 0,1,2,3,4,5,6,7,8,9, .... };

那么转换很容易

int digit_to_int( unsigned char c ) { return lookup[ static_cast<int>(c) ]; }

基本上,这是ctype库的许多实现所采用的方法。您也可以对此进行微调以使其与十六进制数字一起使用。


转换单个十进制(或八进制)数字似乎效率极低。如果查找表的相关部分恰好不在L1高速缓存中,则将浪费很多周期将其拉入以获取一个值。坦率地说,如果您要转换整个数字位数,我倾向于怀疑这甚至是个好主意,但您必须对此进行衡量。当然,对于十六进制而言,它更具竞争力。
dfeuer 2012年

0

检查一下

char s='A';

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

仅适用于0,1,2,....,E,F。


0

只需使用以下atol()功能:

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

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

}

0

例如,如果您的数字是'5'ASCII码,则表示为二进制数0011 0101(53)。每个数字具有最高的四位0011,而最低的四位代表bcd中的数字。所以你只要

char cdig = '5';
int dig = cdig & 0xf; // dig contains the number 5

以获得最低的4位或相同的数字。在asm中,它使用and运算符代替sub(与其他答案一样)。


'5'是53(00110101
eyllanesc

@eyllanesc起初是4。谢谢。编辑。
Garmekain


-2

使用函数:atoi表示数组为整数,atof表示数组为浮点型;要么

char c = '5';
int b = c - 48;
printf("%d", b);

已经有几个答案。这不会增加他们尚未涵盖的内容。
ShadowRanger

-3

您可以将其强制转换为int(或float或double或其他任何您想使用的整数)并将其存储在anoter变量中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.