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

C语言实现Luhn算法时出现Segmentation Fault问题求助

Luhn算法实现的段错误问题修复

问题描述

我正在实现Luhn算法,使用CS50库的get_long获取信用卡号,将各位数字存入数组后传入checksum函数。程序在本地机器运行正常,但在CS50的Codespace中,部分信用卡号(如4003600000000014)会出现**Segmentation Fault(core dumped)**错误。尝试将存储卡号的变量类型从long改为long long,问题仍然存在。

错误原因分析

  • 数组越界写入:填充digits数组的循环逻辑错误,每次i=0时都会将tmp重置为原始卡号,导致循环次数远超卡号位数,写入数组的越界内存区域,触发段错误。
  • 缺少必要头文件:代码使用了bool类型,但未包含stdbool.h,不同编译环境对未定义类型的处理不同,可能引发未定义行为。
  • 变量类型不匹配:主函数中n是int类型,而checksum函数的参数n是size_t类型,类型不兼容可能在特定环境下引发问题。

修复方案

  1. 修正数组填充逻辑:移除循环内重置tmp的代码,在循环前将tmp初始化为卡号,循环中仅执行tmp /=10操作,确保循环次数等于卡号位数。
  2. 添加stdbool.h头文件:确保bool、true、false关键字被正确识别。
  3. 统一变量类型:将主函数中的n改为size_t类型,与checksum函数的参数类型保持一致。

修正后的完整代码

// Implementation of the Luhn's Algorithm

#include <cs50.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>  // 添加必要头文件

int checksum(int digits[], size_t n);

int main()
{
    // Prompt user for credit card number
    long long number = get_long("Number: ");

    // Calculate length of number
    size_t n;  // 改为size_t类型
    long long tmp = number;
    for (n = 0; tmp != 0; n++)
    {
        tmp = tmp / 10;
    }

    // Put the digits in an array and pass it to the checksum function
    tmp = number;
    int digits[n];
    for (size_t i = 0; tmp != 0; i++)  // i也改为size_t
    {
        digits[i] = tmp % 10;
        tmp = tmp / 10;  // 直接在每次循环后除以10,移除错误的重置逻辑
    }
    bool a = checksum(digits, n);

    int first_digit = digits[n - 1];
    int sec_digit = digits[n - 2];

    // Check if number satisfies checksum and corresponding pattern
    // for valid card numbers and prints out the corresponding matching
    // card pattern brand
    if (a && (n == 15 && first_digit == 3) && (sec_digit == 4 || sec_digit == 7))
    {
        printf("AMEX\n");
    }
    else if (a && (n == 13 || n == 16) && (first_digit == 4))
    {
        printf("VISA\n");
    }
    else if (a && (n == 16 && first_digit == 5) && (sec_digit == 1 || sec_digit == 2 || sec_digit == 3 || sec_digit == 4
             || sec_digit == 5))
    {
        printf("MASTERCARD\n");
    }
    else
    {
        printf("INVALID\n");
        return 0;
    }
}

// Checksum implementation
int checksum(int numbers[], size_t n)
{
    // Variable to store result
    int result = 0;

    // Store the numbers array in a duplicate variable
    int duplicate[n];
    for (size_t i = 0; i < n; i++)  // i改为size_t
    {
        duplicate[i] = numbers[i];
    }

    // Loop to add the product's digits'
    for (size_t i = 1; i < n; i += 2)  // i改为size_t
    {
        // Multiply the digits by 2 starting from the second to last digit and their digits' together
        duplicate[i] *= 2;

        // Check if the result is not a single number
        if (duplicate[i] / 10 != 0)
        {
            int tmp = duplicate[i];
            tmp = (tmp / 10) + (tmp % 10);
            result += tmp;
        }
        else
        {
            result += duplicate[i];
        }
    }

    // Add the result to the digits of the numbers we didn't multiply by 2
    for (size_t i = 0; i < n; i += 2)  // i改为size_t
    {
        result += duplicate[i];
    }

    // Return 0 or 1 based on results
    return (result % 10 == 0);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 03:45:00