【问题标题】:how to add char type integer in c如何在c中添加char类型整数
【发布时间】:2012-11-12 13:19:33
【问题描述】:

这是我的程序的示例代码,我要在其中添加两个字符串类型整数(ex: "23568" and "23674")。所以,我尝试使用单个 char 加法。

char first ='2';
char second ='1';

我是这样尝试的..

i=((int)first)+((int)second);
printf("%d",i);

我得到输出 99,因为它添加了两者的 ASCII 值。任何人请建议我,在C中添加char类型编号的方法应该是什么。

【问题讨论】:

  • char *first = "235668"; char second="23674"; ... printf("%d\n", atoi(first)+atoi(second)); 怎么样?
  • 当字符长度为 1000 时它会起作用吗??
  • 嗯,我认为不,即使在 64 位计算机上,100 位数也太多了。 gmplib.org
  • 所以,在那种情况下,它对我没有帮助。因为,在原始问题中,最大限制为 1000 个字符。
  • 查看有关 GNU gmplib“无限制算术”的链接。再次gmplib.org

标签: c char ascii


【解决方案1】:

由于您的示例将两个单个字符加在一起,因此您可以自信地了解两件事

  1. 总数永远不会超过 18 个。
  2. 您可以完全通过库调用避免任何转换。该标准要求 '0' 到 '9' 是连续的(实际上它是标准规定的唯一字符序列)。

因此;

char a = '2';
char b = '3';

int i = (int)(a-'0') + (int)(b-'0');

始终工作。即使在 EBCDIC 中(如果您不知道那是什么,请认为自己很幸运)。

如果您的意图是实际添加两个当前为字符串形式的多个数字(“12345”、“54321”),那么 strtol() 是您的最佳选择。

【讨论】:

  • @Ben 否决票错误,因为答案是针对特定问题而不是针对一般问题。他不打算回答没有被问到的问题,所以我赞成
  • 如果您可以证明此答案中的变量 a 和/或 b 的真实、空灵或其他方式,在时刻 b 被分配 '3' 并计算 i 的值,我将不仅删除“总是工作”,我将彻底删除答案。 OP问了一个具体问题。如果提供的具体答案不适合在他们的字里行间读到的问题,那就这样吧。这就是为什么不止一个人可以回答这个问题(而且很多人都回答了)。但鉴于以上三行代码,always work 不仅正确,而且provably 如此。
  • WhozCraig 是正确的,因为数字 '0' 到 '9' 由标准 5.2.1保证“在源和执行基本字符集中,值上述十进制数字列表中 0 之后的每个字符都应比前一个字符的值大一。”这些是标准保证在符号表中相邻的唯一符号。
  • 如果您要解释 OP 计算单个数字字符加法的整数结果的请求,则需要处理未要求的未定义行为,那就这样吧。如果您更喜欢 set-notation 或正则表达式来限定域限制(OP 未要求),那么也可以。同样,这就是 SO 允许并鼓励多个答案的原因。根据您的猜想,all 两参数到结果的计算需要 3 参数最小值;每个参数一个,结果一个,并返回成功或失败的布尔条件。如果可以的话,我可以忍受。
  • @Lundin 对不起,演员是我的 C++ 方面流血。不时发生。至少在这方面是多余的(在这种情况下)没有奇怪的副作用;在另一面 (C++) 不明确可能会产生灾难性的结果,因为我们都至少处理过一两次。
【解决方案2】:
i=(first-'0')+(second-'0');

无需将 char 转换为 int。

【讨论】:

  • 哦,好答案 :),但我认为他需要一点帮助才能从一种类型转换为另一种类型(我认为)
  • 演员阵容完全没有必要。 '0' 已经是 int,即使不是,整数提升也会应用于 - 的参数,因此无论如何都要在类型 int 上完成算术运算。
  • 确实,不需要类型转换,C++ 人倾向于这样做。
  • 为选角更新了问题。您能否提供一些证明不需要将 char 转换为 int 的链接
  • The C standard 6.3.1.1/2: "If an int can represent all values of the original type... the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. 整数提升又是平衡的一部分(“通常的算术转换”6.3.1.8)。
【解决方案3】:

如果你想添加字符的数字表示,我会使用 "(first - '0') + (second - '0');"

【讨论】:

    【解决方案4】:

    这个问题看起来很有趣,虽然它会比它更容易,但添加“字符串数字”有点棘手(我使用的丑陋方法更是如此)。

    此代码将添加两个任意长度的字符串,它们不需要与从后面开始添加的长度相同。您提供两个字符串,足够长度的缓冲区,并确保字符串仅包含数字:

    #include <stdio.h>
    #include <string.h>
    
    char * add_string_numbers(char * first, char * second, char * dest, int dest_len)
    {
        char * res = dest + dest_len - 1;
        *res = 0;
    
        if ( ! *first && ! *second )
        {
            puts("Those numbers are less than nothing");
            return 0;
        }
    
        int first_len = strlen(first);
        int second_len = strlen(second);
    
        if ( ((first_len+2) > dest_len) || ((second_len+2) > dest_len) )
        {
            puts("Possibly not enough space on destination buffer");
            return 0;
        }
    
        char *first_back = first+first_len;
        char *second_back = second+second_len;
    
        char sum;
        char carry = 0;
    
        while ( (first_back > first) || (second_back > second) )
        {
            sum = ((first_back  > first)  ? *(--first_back) : '0')
                + ((second_back > second) ? *(--second_back) : '0')
                + carry - '0';
    
            carry = sum > '9';
            if ( carry )
            {
                sum -= 10;
            }
    
            if ( sum > '9' )
            {
                sum = '0';
                carry = 1;
            }
    
            *(--res) = sum;
        }
    
        if ( carry )
        {
            *(--res) = '1';
        }
    
        return res;
    }
    
    int main(int argc, char** argv)
    {
        char * a =              "555555555555555555555555555555555555555555555555555555555555555";
        char * b = "9999999999999666666666666666666666666666666666666666666666666666666666666666";
        char r[100] = {0};
    
        char * res = add_string_numbers(a,b,r,sizeof(r));
    
        printf("%s + %s = %s", a, b, res);
    
        return (0);
    }
    

    【讨论】:

      【解决方案5】:

      嗯...你已经添加了字符类型,正如你所指出的那样 4910 和 5010 应该给你 9910

      如果您要问如何添加两个字符的 reperserented 值,即'1' + '2' == 3,您可以减去基数 '0'

      printf("%d",('2'-'0') + ('1'-'0')); 
      

      这将 3 作为 int 给出,因为:

      '0' = ASCII 48<sub>10</sub>
      '1' = ASCII 49<sub>10</sub>
      '2' = ASCII 50<sub>10</sub>
      

      所以你在做:

      printf("%d",(50-48) + (49-48));
      

      如果你想做一个更长的数字,你可以使用atoi(),但是你必须使用字符串:

      int * first = "123";
      int * second = "100";
      printf("%d", atoi(first) + atoi(second));
      
      >> 223
      

      【讨论】:

      • 永远不要使用atoi!改用 strtol 并指定基数 10。atoi 认为 012 是 10,因为它将带有前导零的数字视为八进制。
      • @Ben - atoi() 等价于strtol(nptr, (char **) NULL, 10)(除了错误检查)。这提到了很多地方,包括atoi 的人。使用 gcc 4.6.2 将 char * num = "012"; 传递给 atoi() 与使用 strtol 的结果相同。
      • 谷歌搜索后我发现你是正确的,因为行为在 1990 年被 ANSI 标准 C 改变。然而这个问题在我 2005 年支持的一个全国性应用程序中出现,直到很多时候才开始该标准采用多年后。 (我是根据对K&R的记忆来诊断这个bug的,我没有介绍)。标准需要很长时间才能采用。即便如此,atoi 已被弃用,所以我仍然不赞成。
      • @Ben - atoi is deprecated - 根据您的评论,您是否有比这里问题中的信息更新的信息? stackoverflow.com/questions/2892951/…
      • @Ben - 在这里非常清楚......我刚刚检查了/usr/include/stdlib.h ISO C99 7.20(2011 年版权),它没有提到它已被弃用。通常他们会添加一些 cmets 和 __THROW __attribute_deprecated__; 当它不再有用时。所以如果你有更新的东西表明它不好,我很乐意更新我的帖子。
      【解决方案6】:

      事实上,您甚至不需要使用单个 char 来输入字符来执行此操作:

       #include <stdlib.h>
       #include <stdio.h>
       int main(int argc, char* argv[]) {
           char f1 = '9';
           char f2 = '7';
           int v = (f1 - '0') - (f2 - '0');
           printf("%d\n", v);
      
           return 0;
       }
      

      将打印2

      但是注意,它不适用于十六进制字符

      【讨论】:

        【解决方案7】:

        如果你想逐个扫描数字,简单的atoi函数就可以了

        【讨论】:

        • atoi 已弃用。使用 strotl 并指定基数 10。
        • @Ben 实际上,虽然strtol 确实更喜欢,但 atoi 仍然有效。该标准实际上将 atoi 定义为等于(int)strtol(nptr, (char **)NULL, 10)
        • 我基本上是一个固件开发人员,所以,如果我需要这样的转换,我通常会选择最简单和最合适的解决方案,希望能节省代码ROM。在开发 PC 应用程序时,我会考虑 strtol。谢谢你们!
        【解决方案8】:

        你可以使用 atoi() 函数

        #include <stdio.h>
        #include <stdlib.h>
        void main(){
            char f[] = {"1"};
            char s[] = {"2"};
            int i, k;
            i = atoi(f);
            k = atoi(s);
            printf("%d", i + k);
            getchar();
        }
        

        希望我回答了你的问题

        【讨论】:

        • strtol 更好,因为它具有明确定义的错误处理。如果输入无效输入,atoi 将停止并着火。
        • atoi 已弃用。使用 strotl 并指定基数 10。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-19
        • 2012-11-17
        • 2016-03-07
        • 1970-01-01
        • 2018-11-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多