CS50信用卡校验代码中else if分支失效问题求助
哈佛CS50信用卡验证程序卡种识别故障排查
我为哈佛CS50课程编写了信用卡号码验证程序,流程为:获取卡号 → 验证位数合法性 → 通过校验和判断有效性 → 识别卡种。目前校验和功能正常,但卡种识别逻辑存在问题:当卡号首数字为3、次数字为7(符合AMEX卡规则)时,程序无法正确识别,始终返回INVALID。请问这部分的else if分支为何无法正常工作?
问题代码
#include <cs50.h> #include <stdio.h> #include <stdbool.h> long get_number(void); int get_digits(long creditnumber); int calcfirst(long creditnumber); bool checksum(long creditnumber, int digits); int main(void) { long creditnumber = get_number(); int digits = get_digits(creditnumber); int firstdigit = calcfirst(creditnumber); int seconddigit = calcfirst(creditnumber); if (digits != 13 && digits != 15 && digits != 16) { printf("INVALID\n"); } else { if (checksum(creditnumber, digits)) { if (firstdigit == 4) { printf("VISA\n"); } else if (firstdigit == 5 && (seconddigit > 0 && seconddigit < 6)) { printf("MASTERCARD\n"); } else if (firstdigit == 3 && (seconddigit == 4 || seconddigit == 7)) { printf("AMEX\n"); } else { printf("INVALID\n"); } } else { printf("INVALID\n"); } } return 0; } long get_number(void) { long creditnumber = get_long("Number: "); return creditnumber; } int get_digits(long creditnumber) { int digits = 0; do { creditnumber /= 10; digits++; } while (creditnumber != 0); return digits; } int calcfirst(long creditnumber) { int firstdigit; int seconddigit; int firstnum; long n = creditnumber; while (n > 100) { n /= 10; } firstnum = n; firstdigit = firstnum / 10; seconddigit = firstnum % 10; return firstdigit; return seconddigit; }
故障原因
核心问题出在calcfirst函数的返回逻辑:
- 函数中连续写了两个
return语句:return firstdigit;执行后,程序会立即退出函数,后续的return seconddigit;永远不会被执行。 - 在
main函数中,firstdigit和seconddigit都是通过调用calcfirst(creditnumber)赋值的,因此两者拿到的都是第一位数字,而非预期的第一位和第二位。 - 以AMEX卡为例,卡号首数字是3,此时
seconddigit的值也是3,自然无法满足seconddigit ==4 || seconddigit ==7的判断条件,导致分支失效。
修复方案
方案一:用指针传递获取两位数字
修改calcfirst函数,通过指针参数同时返回第一位和第二位数字,避免重复计算:
void calcfirst(long creditnumber, int *firstdigit, int *seconddigit) { long n = creditnumber; while (n > 100) { n /= 10; } int firstnum = n; *firstdigit = firstnum / 10; *seconddigit = firstnum % 10; }
然后在main函数中调整调用方式:
int firstdigit, seconddigit; calcfirst(creditnumber, &firstdigit, &seconddigit);
方案二:拆分函数分别获取
如果不想用指针,可以拆分为两个独立函数:
int getFirstDigit(long creditnumber) { long n = creditnumber; while (n >= 10) { n /= 10; } return n; } int getSecondDigit(long creditnumber) { long n = creditnumber; while (n >= 100) { n /= 10; } return n % 10; }
在main函数中分别调用:
int firstdigit = getFirstDigit(creditnumber); int seconddigit = getSecondDigit(creditnumber);
内容的提问来源于stack exchange,提问作者Jack Finnegan
相关产品推荐
相关产品推荐

