CS50课程:C语言信用卡验证程序故障排查与优化求助
解决CS50信用卡验证程序的无输出问题
你的程序目前存在逻辑漏洞:当卡号通过了长度校验和Luhn算法校验,但不属于Visa、American Express、MasterCard这三类时,没有任何输出语句被触发。因为现有代码里,INVALID只在长度不合法或Luhn校验失败时输出,而卡种匹配的if都是独立判断,不匹配就不会执行任何输出操作。
修复思路
引入一个状态变量跟踪卡的有效性,默认标记为无效,只有当卡号通过所有校验且匹配指定卡种时,才更新状态为对应卡种,最后统一输出结果,确保所有场景都有明确输出。
修改后的完整代码
#include <cs50.h> #include <stdio.h> // AMEX 34, 37; MASTERCARD 51-55; VISA 4 // 合法长度:13, 15, 16 位 int main(void) { long long number = get_long("Credit Card Number: "); long long cc = number; int length = 0; char status = 'I'; // 默认标记为无效(Invalid) // 计算卡号长度 while (cc > 0) { cc /= 10; length++; } // 提取前两位和第一位数字 long long cc1 = number; for (int x = 0; x < length - 2; x++) { cc1 /= 10; } int firsttwo = cc1; int first = cc1 / 10; // Luhn算法校验 long long i = number; int d; int sum = 0; while (i > 0) { d = i % 10; sum += d; i /= 100; } long long y = number / 10; int d2; int prod = 0; int sum2 = 0; while (y > 0) { d2 = y % 10; prod = d2 * 2; if (prod >= 10) { prod = prod - 9; } sum2 += prod; y /= 100; } int total = sum + sum2; // 仅当长度合法且Luhn校验通过时,才判断卡种 if ((length == 13 || length == 15 || length == 16) && (total % 10 == 0)) { if ((length == 13 || length == 16) && first == 4) { status = 'V'; // Visa } else if (length == 15 && (firsttwo == 34 || firsttwo == 37)) { status = 'A'; // American Express } else if (length == 16 && (firsttwo >= 51 && firsttwo <= 55)) { status = 'M'; // MasterCard } // 不匹配以上卡种时,status保持'I' } // 统一输出结果 switch(status) { case 'V': printf("VISA\n"); break; case 'A': printf("AMEX\n"); break; case 'M': printf("MASTERCARD\n"); break; default: printf("INVALID\n"); break; } }
关键修改点
- 将所有存储卡号的
long类型改为long long,避免16位卡号超出32位整数范围导致溢出。 - 新增
status变量统一管理输出状态,覆盖「长度非法」「Luhn校验失败」「卡种不匹配」等所有无效场景。 - 将卡种判断嵌套在「长度合法+Luhn校验通过」的大条件中,逻辑更严谨——只有基础校验通过,才需要判断卡种。
- 用
else if替代独立if,避免逻辑冗余,同时保证同一卡号只匹配一种卡种。 - 通过
switch统一输出,确保无论什么情况都有明确的输出结果。
内容的提问来源于stack exchange,提问作者noah-jawn
相关产品推荐
相关产品推荐

