求助:信用卡号掩码函数的创建与调用代码错误排查
信用卡号掩码功能C语言代码错误排查与修复
问题描述
我想用C语言实现信用卡号(或任意字符串)的掩码功能:保留最后4位字符,其余前置字符替换为#;若字符串长度≤4则原样保留。但编写的代码运行出错,出现负数相关错误,请求排查问题。
原错误代码
#include <stdio.h> #include <string.h> char *maskify(char *masked,const char *string); main(void) { char string; char display; char credit[9]; printf("Enter credit card no: "); scanf("%s", &credit); display = maskify(credit,string); printf("Is credit card no: %s",display); } char *maskify(char *masked, const char *string) { int n = strlen(strcpy(masked,string))- 4; if(n > 0)memset(masked ,'#' ,n); return masked; }
预期功能测试用例
以下是功能需覆盖的测试场景:
- 输入
"4556364607935616",输出"############5616" - 输入
"64607935616",输出"#######5616" - 输入
"12345",输出"#2345" - 输入
"1234",输出"1234" - 输入
"123",输出"123" - 输入
"12",输出"12" - 输入
"1",输出"1" - 输入
"",输出"" - 输入
"Skippy",输出"##ippy" - 输入
"Nananananananananananananananana Batman!",输出"####################################man!"
错误点分析
- 变量类型错误:
char string;和char display;定义为单个字符类型,但实际需要存储字符串指针,应该改为char *string;和char *display;。 - scanf参数错误:
scanf("%s", &credit);中credit是数组名,本身就是首地址,无需取地址符&,直接写credit即可。 - 函数调用参数错误:调用
maskify时,第二个参数传了未初始化的string变量,应该传入输入的字符串credit;同时原函数的参数设计不合理,没必要把目标缓冲区和源字符串分开传递。 - 负数处理缺失:当字符串长度≤4时,
strlen(...) -4会得到负数,虽然if(n>0)跳过了memset,但原代码中调用maskify时的参数传递完全错误,导致string是无效地址,触发内存访问错误。
修正后的代码
#include <stdio.h> #include <string.h> char *maskify(char *dest, const char *src) { // 先把源字符串复制到目标缓冲区 strcpy(dest, src); size_t len = strlen(dest); // 只处理长度大于4的情况 if (len > 4) { // 计算需要替换的字符数,避免负数 size_t mask_len = len - 4; memset(dest, '#', mask_len); } return dest; } int main(void) { // 扩大缓冲区,避免输入过长字符串溢出 char credit[100]; printf("Enter credit card no: "); // 限制输入长度,防止缓冲区溢出 scanf("%99s", credit); char *display = maskify(credit, credit); printf("Masked credit card no: %s\n", display); // 测试用例验证 char test_buf[200]; printf("\n测试用例验证:\n"); printf("输入\"4556364607935616\" → 输出%s\n", maskify(test_buf, "4556364607935616")); printf("输入\"64607935616\" → 输出%s\n", maskify(test_buf, "64607935616")); printf("输入\"12345\" → 输出%s\n", maskify(test_buf, "12345")); printf("输入\"1234\" → 输出%s\n", maskify(test_buf, "1234")); printf("输入\"123\" → 输出%s\n", maskify(test_buf, "123")); printf("输入\"12\" → 输出%s\n", maskify(test_buf, "12")); printf("输入\"1\" → 输出%s\n", maskify(test_buf, "1")); printf("输入空字符串 → 输出\"%s\"\n", maskify(test_buf, "")); printf("输入\"Skippy\" → 输出%s\n", maskify(test_buf, "Skippy")); printf("输入\"Nananananananananananananananana Batman!\" → 输出%s\n", maskify(test_buf, "Nananananananananananananananana Batman!")); return 0; }
修正说明
- 调整了
maskify函数的参数逻辑,明确区分源字符串和目标缓冲区,避免参数混淆。 - 使用
size_t类型存储字符串长度和掩码长度,彻底避免负数问题(size_t是无符号整数类型)。 - 扩大输入缓冲区并限制
scanf输入长度,防止缓冲区溢出。 - 新增了测试用例的验证代码,方便直接查看功能是否符合预期。
内容的提问来源于stack exchange,提问作者Brian Noel
相关产品推荐
相关产品推荐

