【问题标题】:Char to int conversion in CC中的char到int转换
【发布时间】:2010-10-21 08:48:35
【问题描述】:

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

char c = '5';

而且我希望c 持有5 而不是'5',这样做是不是100% 便携?

c = c - '0';

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

【问题讨论】:

  • @Binary- 重复发布的是 C++,即使答案相同,它也适用于不同的语言

标签: c char


【解决方案1】:

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

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

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

没有库函数可以为单个char 执行此操作,您需要先构建一个字符串:

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

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

您也可以使用@987654322@ 函数进行转换,一旦你有一个字符串,但@987654323@ 更好更安全。

正如评论者所指出的,调用函数来进行这种转换是非常过分的;您最初减去“0”的方法是正确的方法。我只是想在这里展示如何使用推荐的将数字作为字符串转换为“真实”数字的标准方法。

【讨论】:

  • 这是一种非常复杂且昂贵的方法来执行非常直接的操作,即 int i = d - '0'
  • 这是您问题的答案,但不是最佳答案。这是矫枉过正。你用 c=c-'0'; 回答了你自己的问题。 - 这是最好的答案。
  • 是的,当然使用函数是矫枉过正的。也许我应该在这方面更清楚。
  • 矫枉过正的不仅仅是功能方面。使用 strtol 也是大材小用。
  • 这个答案没有解决这个问题的可移植性方面。此功能不可移植。它不适用于多字节字符集。当试图传入 wchar_t 类型的变量时,char d 参数会产生编译器错误。
【解决方案2】:

试试这个:

char c = '5' - '0';

【讨论】:

    【解决方案3】:
    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 */
    }
    

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

    【讨论】:

    • ctype.h 提供了以下用于执行验证的函数/宏:isdigit、isxdigit、isspace 等等。请参阅手册页。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      由于您只转换一个字符,因此 atoi() 函数是多余的。 atoi() 在转换数字的字符串表示时很有用。其他帖子已经给出了这方面的例子。如果我正确阅读了您的帖子,则您只转换了一个数字字符。因此,您只需要转换 0 到 9 范围内的字符。在只转换一个数字字符的情况下,您建议减去“0”会给您想要的结果。这样做的原因是因为 ASCII 值是连续的(就像你说的那样)。因此,从数字字符中减去 ASCII 值 0(ASCII 值 48 - 请参阅 ASCII Table 获取值)将得到数字的值。所以,你的例子 c = c - '0' 其中 c = '5',真正发生的是 53(5 的 ASCII 值)- 48(0 的 ASCII 值)= 5。

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          通常,如果不能保证您的输入在 '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
          }
          

          附:我知道这是一个矫枉过正。我只是想把它作为一种可能不会立即显现出来的替代解决方案。

          【讨论】:

            【解决方案8】:

            正如其他人所建议的,但包装在一个函数中:

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

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

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

            【讨论】:

              【解决方案9】:

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

              【讨论】:

                【解决方案10】:

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

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

                【讨论】:

                  猜你喜欢
                  • 2012-10-20
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-11-27
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多