CS50 credit.c信用卡验证程序两个无效卡号误识别为VISA问题
问题描述
我目前遇到的错误集中在数学计算逻辑部分,所有尝试的修改方案都没有生效。
附:抱歉问题格式不够规范,这是我第一次使用Stack Overflow。
测试用例运行结果如下:
- :) credit.c 存在
- :) credit.c 编译通过
- :) 识别378282246310005为AMEX
- :) 识别371449635398431为AMEX
- :) 识别5555555555554444为MASTERCARD
- :) 识别5105105105105100为MASTERCARD
- :) 识别4111111111111111为VISA
- :) 识别4012888888881881为VISA
- :) 识别4222222222222为VISA
- :) 识别1234567890为INVALID
- :) 识别369421438430814为INVALID
- :) 识别4062901840为INVALID
- :) 识别5673598276138003为INVALID
- :( 识别4111111111111113为INVALID,预期输出"INVALID\n",实际输出"VISA\n"
- :( 识别4222222222223为INVALID,预期输出"INVALID\n",实际输出"VISA\n"
原代码如下:
#include <cs50.h> #include <math.h> // 提示用户输入信用卡号 int main(void) { long credit_card, credit_number; do { credit_card = get_long("Enter credit card number: "); } while (credit_card < 0); credit_number = credit_card; // 计算总位数 int count = (credit_number == 0) ? 1 : (log10(credit_number) + 1); int summation = 0; while (credit_number == 0) { int x = credit_number % 10; summation += x; int y = 2 * ((credit_number / 10) % 10); int r = (y % 10) + floor((y / 10) % 10); summation += r; credit_number /= 100; } string card; // 识别输入的信用卡号对应的卡类型 int test = cc / pow(10, count - 2); if ((count == 13 || count == 16) && test / 10 == 4) { card = "VISA"; } else if (count == 16 && test >= 51 && test <= 55) { card = "MASTERCARD"; } else if (count == 15 && (test == 34 || test == 37)) { card = "AMEX"; } else { card = "INVALID"; } // 最终校验 if (sum % 10 == 0) { printf("%s\n", card); } else { printf("INVALID\n"); } }
问题原因
- Luhn算法的循环条件错误:你写的
while (credit_number == 0)永远不会触发循环,求和变量summation始终为0,最终校验sum%10==0永远成立,只要卡号开头符合卡种规则就会直接输出卡种,跳过了校验逻辑,这是两个失败用例的核心原因。 - 变量名未定义/不匹配:计算卡号前缀时使用的
cc未定义,应该替换为存储原始卡号的credit_card;最终校验时使用的sum也未定义,应该替换为你定义的求和变量summation。 - 浮点数精度问题:使用
log10、pow这类浮点运算函数处理整数逻辑,大概率会出现精度误差,建议改用纯整数运算计算位数和卡号前缀。
修改后的完整代码
#include <cs50.h> #include <stdio.h> int main(void) { long credit_card, credit_number; do { credit_card = get_long("Enter credit card number: "); } while (credit_card < 0); credit_number = credit_card; // 整数运算计算总位数,避免浮点精度问题 int count = 0; long temp = credit_card; while (temp > 0) { temp /= 10; count++; } int summation = 0; temp = credit_number; // 修正循环条件,正确执行Luhn算法 while (temp > 0) { int x = temp % 10; summation += x; temp /= 10; if (temp == 0) break; int y = 2 * (temp % 10); summation += (y % 10) + (y / 10); temp /= 10; } // 整数运算计算卡号前两位 long prefix = credit_card; while (prefix >= 100) { prefix /= 10; } string card = "INVALID"; // 识别卡类型 if ((count == 13 || count == 16) && prefix / 10 == 4) { card = "VISA"; } else if (count == 16 && prefix >= 51 && prefix <= 55) { card = "MASTERCARD"; } else if (count == 15 && (prefix == 34 || prefix == 37)) { card = "AMEX"; } // 修正变量名,执行最终校验输出 if (summation % 10 == 0) { printf("%s\n", card); } else { printf("INVALID\n"); } }
内容的提问来源于stack exchange,提问作者user16908074
相关产品推荐
相关产品推荐

