C中的char到int转换

时间:2009-04-23 13:25:30

标签: c char

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

char c = '5';

并且我希望c保留5而不是'5',它是100%可移植的吗?

c = c - '0';

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

10 个答案:

答案 0 :(得分:27)

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

  

基本源和基本执行字符集应具有以下内容   成员:
  [...]
  10位小数位数
         0 1 2 3 4 5 6 7 8 9
  [...]
  在源和执行基本字符集中,   上述小数位数列表中0后的每个字符的值应大于1   以前的价值。

ASCII和EBCDIC以及从它们派生的字符集都满足这一要求,这就是C标准能够强加它的原因。请注意,字母连续iN EBCDIC,而C不要求它们。

单个char没有库函数,你需要先构建一个字符串:

int digit_to_int(char d)
{
 char str[2];

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

一旦有字符串,您也可以使用atoi()函数进行转换,但strtol()更好更安全。

正如评论者指出的那样,调用函数进行这种转换是极端的过度杀伤力;你最初减去'0'的方法是这样做的正确方法。我只想说明如何使用推荐的标准方法将数字转换为字符串转换为“真实”数字。

答案 1 :(得分:9)

试试这个:

char c = '5' - '0';

答案 2 :(得分:5)

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

答案 3 :(得分:5)

int i = c - '0';

你应该知道这不会对角色进行任何验证 - 例如,如果角色是'a'那么你会得到91 - 48 = 49.特别是如果你正在处理用户或网络输入,您应该执行验证以避免程序中的不良行为。只需检查范围:

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

请注意,如果您希望转换处理十六进制数字,您可以检查范围并执行适当的计算。

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 */
}

这会将单个十六进制字符(大写或小写独立)转换为整数。

答案 4 :(得分:2)

由于您只转换一个字符,因此atoi()函数过度。如果要转换数字的字符串表示,atoi()非常有用。其他帖子举例说明了这一点。如果我正确阅读了您的帖子,您只会转换一个数字字符。因此,您只需要转换0到9范围内的字符。在仅转换一个数字字符的情况下,您建议减去“0”将为您提供所需的结果。这有效的原因是因为ASCII值是连续的(就像你说的那样)。因此,从数字字符中减去ASCII值0(ASCII值48 - 参见值ASCII Table)将给出数字的值。所以,你的例子是c = c - '0',其中c ='5',实际发生的是53(ASCII值为5) - 48(ASCII值为0)= 5.

当我第一次发布这个答案时,我没有考虑你关于在不同字符集之间100%移植的评论。我做了一些进一步环顾四周,似乎你的答案仍然大多是正确的。问题是您使用的是8位数据类型的char。哪个不适用于所有字符类型。请阅读Joel Spolsky on Unicode的这篇文章,了解有关Unicode的更多信息。在这篇文章中,他说他使用wchar_t作为字符。这对他来说效果很好,他以29种语言出版了他的网站。因此,您需要将char更改为wchar_t。除此之外,他说127以下的角色基本相同。这将包括代表数字的字符。这意味着你提出的基本数学应该适用于你想要实现的目标。

答案 5 :(得分:1)

是。只要您使用标准的ascii字符,这就是安全的,就像您在此示例中一样。

答案 6 :(得分:0)

通常情况下,如果无法保证您的输入位于“0”..“9”范围内,则必须执行以下检查:

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

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

// 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
}

P.S。我知道这是 overkill 。我只是想把它作为一种可能不会立即明显的替代解决方案。

答案 7 :(得分:0)

正如其他人所建议的,但包含在一个功能中:

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

现在只需使用该功能。如果,在线下,您决定使用不同的方法,您只需要更改实现(性能,字符集差异,无论如何),您将不需要更改调用者。

此版本假定c包含表示数字的char。您可以在调用函数之前使用ctype.h的isdigit函数检查它。

答案 8 :(得分:0)

由于'0','1','2'....的ASCII码从48到57放置,因此它们基本上是连续的。现在算术运算需要将char数据类型转换为int数据类型。你基本上做的是:  53-48因此它存储了值5,您可以使用它来执行任何整数运算。注意,在从int转换回char时,编译器不会给出错误,只是执行模256操作以将值放在可接受的范围内

答案 9 :(得分:0)

您只需使用atol()功能:

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

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

}