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

求助:信用卡号掩码函数的创建与调用代码错误排查

信用卡号掩码功能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!"

错误点分析

  1. 变量类型错误:char string; 和 char display; 定义为单个字符类型,但实际需要存储字符串指针,应该改为char *string; 和 char *display;。
  2. scanf参数错误:scanf("%s", &credit); 中credit是数组名,本身就是首地址,无需取地址符&,直接写credit即可。
  3. 函数调用参数错误:调用maskify时,第二个参数传了未初始化的string变量,应该传入输入的字符串credit;同时原函数的参数设计不合理,没必要把目标缓冲区和源字符串分开传递。
  4. 负数处理缺失:当字符串长度≤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;
}

修正说明

  1. 调整了maskify函数的参数逻辑,明确区分源字符串和目标缓冲区,避免参数混淆。
  2. 使用size_t类型存储字符串长度和掩码长度,彻底避免负数问题(size_t是无符号整数类型)。
  3. 扩大输入缓冲区并限制scanf输入长度,防止缓冲区溢出。
  4. 新增了测试用例的验证代码,方便直接查看功能是否符合预期。

内容的提问来源于stack exchange,提问作者Brian Noel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:05:22