You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言提取字符串数字求和时atoi使用异常问题排查

问题背景

需求为C语言场景下实现功能:接收用户键盘输入的字符串,提取字符串中所有数字字符对应的单个整数值并累加求和。例如输入字符串C35#37时,程序应计算3+5+3+7,最终输出结果18。
原实现思路是通过strlen获取字符串长度,遍历每个下标位置,调用atoi完成字符转整数,原思路误以为非数字字符传入atoi会返回0,以此自动区分普通字符与数字,但程序运行结果不符合预期。
原问题代码如下:

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

int main(void)
{
    char str[200];

    int len, i,sum=0;

    fputs("문자열을 입력해 주세요: ",stdout);
    fgets(str,sizeof(str),stdin);

    len = strlen(str);
    for(i=0; i<len; i++)
    {
      sum= sum + atoi(&str[i]);
    }
    printf("%d",sum);

    return 0;

}

异常运行结果:

  • 输入a12时,输出14(预期结果应为3)
  • 输入123时,输出149(预期结果应为6)
错误原因

核心问题是对atoi函数的行为理解错误:

  1. atoi的入参是C字符串(以'\0'结尾的字符序列)的起始地址,函数会从该地址开始连续读取字符,直到碰到非数字字符或字符串结束符,将读取到的连续数字序列转换为整数返回,并非只转换当前地址对应的单个字符。
  2. 以输入a12为例:
    • i=0时传入&str[0],指向字符串"a12",开头为非数字,atoi返回0
    • i=1时传入&str[1],指向字符串"12",atoi读取连续数字1、2,返回12
    • i=2时传入&str[2],指向字符串"2",atoi返回2
    • 累加结果0+12+2=14,和异常结果完全吻合
  3. 以输入123为例:
    • i=0时传入&str[0],指向"123",返回123
    • i=1时传入&str[1],指向"23",返回23
    • i=2时传入&str[2],指向"3",返回3
    • 累加结果123+23+3=149,和第二个异常结果完全吻合
  4. 额外冗余问题:fgets读取输入时会将用户输入的换行符\n存入字符串,原实现会遍历到这个换行符,虽然不会影响计算结果,但属于无意义操作。
修复方案

不需要使用atoi处理单个数字字符:C标准中规定数字字符'0'到'9'的ASCII值是连续递增的,单个数字字符减去'0'即可得到对应的整数值。遍历过程中只需要判断当前字符是否为数字字符,是就累加对应数值,非数字直接跳过即可。
修复后的代码:

#include<stdio.h>

int main(void)
{
    char str[200];
    int i, sum = 0;

    fputs("문자열을 입력해 주세요: ", stdout);
    fgets(str, sizeof(str), stdin);

    for(i = 0; str[i] != '\0'; i++)
    {
        // 判断当前字符是否为数字
        if(str[i] >= '0' && str[i] <= '9')
        {
            sum += str[i] - '0';
        }
    }
    printf("%d\n", sum);

    return 0;
}

修复后验证:

  • 输入C35#37,累加3+5+3+7=18,符合需求
  • 输入a12,累加1+2=3,结果正确
  • 输入123,累加1+2+3=6,结果正确

内容的提问来源于stack exchange,提问作者chobodark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 10:30:56