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

C语言实现Luhn算法时atoi函数传参报错问题调试求助

问题根因
  • atoi 函数的入参要求是以\0结尾的C字符串(const char*类型),你直接传入char类型的单个字符,自然会触发「整数转指针类型不兼容」的编译错误。
  • 你给单个字符加&取地址符后虽然绕过了编译校验,但拿到的地址仅对应单个字符的内存空间,后面没有\0作为字符串结束标记,atoi执行时会一直向后读取非法内存,触发访问越界导致程序崩溃。
修复方法

单个数字字符转整数不需要调用atoi,利用ASCII码的特性即可:数字字符'0'到'9'的ASCII值是连续递增的,直接用字符 - '0'就能得到对应的整数值,例如'3' - '0'的计算结果就是整数3。
你只需要把代码中所有atoi(cardnumber[下标])的写法,全部替换成cardnumber[下标] - '0'即可解决核心报错。

其他代码问题优化

你的现有代码还有几处逻辑漏洞需要调整:

  1. 输入校验逻辑中,检测到非数字字符打印提示后,需要立即退出程序,否则后续逻辑仍会执行错误的计算。
  2. 硬编码了16位卡号的下标访问,若用户输入长度不足16位会触发数组越界,建议先判断输入卡号的长度是否符合要求。
  3. 可以用循环实现Luhn算法,避免硬编码多个变量,适配不同长度的银行卡号。
修改后的完整可运行代码
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main(void)
{
    char cardnumber[20]; // 扩大数组长度适配更长的卡号
    printf("Enter your card number: ");
    scanf("%s", cardnumber);
    
    int len = strlen(cardnumber);
    // 先校验所有字符都是数字
    for (int c = 0; c < len; c++)
    {
        if (isdigit(cardnumber[c]) == 0)
        {
            printf("Invalid entry.\n");
            return 1;
        }
    }
    
    int sum = 0;
    // 通用Luhn算法实现
    for (int i = 0; i < len - 1; i++) {
        int digit = cardnumber[len - 2 - i] - '0';
        if (i % 2 == 0) {
            digit *= 2;
            sum += digit / 10 + digit % 10;
        } else {
            sum += digit;
        }
    }
    int checkdigit = cardnumber[len - 1] - '0';
    int check = sum % 10;
    int expected = check == 0 ? 0 : 10 - check;
    
    if (expected == checkdigit) {
        printf("Your card is accepted.\n");
    } else {
        printf("Invalid entry.\n");
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:54:04