在C中将char转换为int

如果我想将单个数字char转换为数字值,例如,如果:

 char c = '5'; 

我想c5而不是'5' ,这是100%的便携式这样做吗?

 c = c - '0'; 

我听说所有的字符集都按照连续顺序存储数字,所以我假设如此,但是我想知道是否有组织的库函数来执行此转换,以及它是如何完成的。 我是一个真正的初学者:)

是的,这是一个安全的转换。 C要求它工作。 这个保证在最新的ISO C标准的5.2.1节第2段中,最近的草案是N1570 :

基本来源和基本执行字符集都应具有以下成员:
[…]
十位十进制数字
0 1 2 3 4 5 6 7 8 9
[…]
在源和执行基本字符集中,上述十进制数字列表中的0之后的每个字符的值应该大于前一个的值。

ASCII和EBCDIC以及由它们派生的字符集都满足这个要求,这就是为什么C标准能够强加它。 请注意,在EBCDIC中,字母不是连续的,C不需要它们。

没有库函数为一个char ,你需要先build立一个string:

 int digit_to_int(char d) { char str[2]; str[0] = d; str[1] = '\0'; return (int) strtol(str, NULL, 10); } 

一旦你有一个string,你也可以使用atoi()函数来进行转换,但是strtol()更好更安全。

正如评论者指出的那样,调用一个函数来完成这个转换是极端矫枉过正; 你最初的方法减去“0”是这样做的正确方法。 我只想说明如何使用推荐的标准方法将数字转换为“真实”数字。

尝试这个 :

 char c = '5' - '0'; 

你可以使用atoi ,它是标准库的一部分。

 int i = c - '0'; 

你应该知道,这不会对字符进行任何validation – 例如,如果字符是'a',那么你会得到91 – 48 = 49。特别是如果你正在处理用户或networkinginput,你可能应该执行validation以避免程序中的不良行为。 只要检查范围:

 if ('0' <= c && c <= '9') { i = c - '0'; } else { /* handle error */ } 

请注意,如果您希望转换处理hex数字,则可以检查范围并执行相应的计算。

 if ('0' <= c && c <= '9') { i = c - '0'; } else if ('a' <= c && c <= 'f') { i = 10 + c - 'a'; } else if ('A' <= c && c <= 'F') { i = 10 + c - 'A'; } else { /* handle error */ } 

这将把一个单独的hex字符,大小写独立,转换成一个整数。

既然你只是转换一个字符,函数atoi()是矫枉过正的。 如果要转换数字的string表示forms,atoi()会很有用。 其他职位已经给出了这个例子。 如果我正确地阅读你的文章,你只能转换一个数字字符。 所以,你只是要转换范围为0到9的字符。在只转换一个数字字符的情况下,你的build议减去'0'会给你你想要的结果。 这个原因是因为ASCII值是连续的(就像你说的)。 因此,从数字字符中减去0的ASCII值(ASCII值48 – 请参阅ASCII表的值)将给出数字的值。 所以,你的例子c = c – '0',其中c ='5',实际发生的是53(ASCII值为5) – 48(ASCII值为0)= 5。

当我第一次发布这个答案时,我没有考虑到你对不同字符集之间的100%可移植性的评论。 我做了一些进一步环顾四周,似乎你的答案仍然是最正确的。 问题是你正在使用一个8位数据types的字符。 这不适用于所有的字符types。 关于Unicode的更多信息,请阅读Joel Spolsky撰写的关于Unicode的文章。 在这篇文章中,他说他使用wchar_t来表示字符。 这对他来说效果很好,他以29种语言出版他的网站。 所以,你需要把你的char改成wchar_t。 除此之外,他说价值在127以下的人物基本上是一样的。 这将包括代表数字的字符。 这意味着你提出的基本math应该为你想要达到的目的而工作。

是。 只要你使用标准的ascii字符,这是安全的,就像你在这个例子中一样。

通常情况下,如果不能保证您的input处于“0”,“9”范围内,则必须执行如下所示的检查:

 if (c >= '0' && c <= '9') { int v = c - '0'; // safely use v } 

另一种方法是使用查找表。 您可以使用更less的(也可能更快的)代码进行简单的范围检查转换:

 // one-time setup of an array of 256 integers; // all slots set to -1 except for ones corresponding // to the numeric characters static const int CHAR_TO_NUMBER[] = { -1, -1, -1, ..., 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // '0'..'9' -1, -1, -1, ... }; // Now, all you need is: int v = CHAR_TO_NUMBER[c]; if (v != -1) { // safely use v } 

PS我知道这是一个矫枉过正的问题 。 我只是想把它作为替代解决scheme,可能不会立即显现。

正如其他人所build议的,但包裹在一个function:

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

现在只需使用该function。 如果你决定使用不同的方法,你只需要改变实现(性能,字符集差异,不pipe),你不需要改变调用者。

这个版本假定c包含一个代表数字的字符。 你可以在调用函数之前检查一下,使用ctype.h的isdigit函数。

由于“0”,“1”,“2”……的ASCII代码从48到57,所以基本上是连续的。 现在,算术运算需要将char数据types转换为int数据types。因此,你基本上做的是:53-48,因此它存储值5,你可以做任何整数运算。注意,当从int转换回char时,编译器不给出错误,只是执行一个模256运算来将该值置于可接受的范围内

你可以简单地使用atol()函数:

 #include <stdio.h> #include <stdlib.h> int main() { const char *c = "5"; int d = atol(c); printf("%d\n", d); }