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

C语言银行客户结构体程序printf打印表格仅最后姓名输出异常问题

问题原因
  • 结构体柔性数组使用错误:C 语言中不指定长度的末尾数组成员(柔性数组)不占用结构体本身的内存空间,无法直接用于声明结构体数组。原代码中struct CustomerData n[2]的每个元素的name字段都没有分配合法的内存空间,输入姓名时会发生越界写操作,前面客户的姓名数据会被后续输入覆盖,因此只有最后一名客户的姓名数据保留正常。
  • 输出逻辑错误:puts()函数的作用是直接输出字符串并自动换行,返回值为int类型(输出成功返回非负整数,失败返回EOF)。原代码将puts(n[i].name)的返回值作为printf("%c")的参数输出,本质是把整数转成字符打印,完全不符合打印姓名的逻辑,是输出乱码的直接原因。
  • 额外的未定义/不安全用法:fflush(stdin)是C标准未定义的行为,不同编译器实现逻辑不一致,无法可靠清空输入缓冲区;gets()函数已被C标准废弃,没有边界检查,极易触发缓冲区溢出漏洞。
修复方案
  1. 修改结构体定义,给姓名字段指定固定长度(例如设置为50个字符足够存储普通姓名),替换柔性数组用法。
  2. 调整输出逻辑,使用printf("%s")直接输出姓名字符串,不要混用puts和printf的参数。
  3. 替换不安全的输入处理逻辑:用scanf(" %[^\n]")(前面加空格吃掉之前遗留的换行符)替代fflush(stdin)+gets()的组合,避免未定义行为。
  4. 可以将结构体数组的长度定义为宏,方便后续修改为题目要求的200个客户上限。
修复后完整代码
#include <stdio.h>
// 定义客户上限和姓名最大长度
#define MAX_CUSTOMER 200
#define NAME_MAX_LEN 50

struct CustomerData {
   int acNum;
   float balance;
   char name[NAME_MAX_LEN + 1]; // 多留1位存字符串结束符'\0'
} n[MAX_CUSTOMER];

int main() {
    int test_cnt = 2; // 测试2个客户,可改为MAX_CUSTOMER适配业务需求
    for(int i = 0; i < test_cnt; i++) {
        printf("give Ac. no. of %d customer\n", i+1);
        scanf("%d", &n[i].acNum);
        printf("balance of customer %d\n", i+1);
        scanf("%f", &n[i].balance);
        printf("Name of customer %d\n", i+1);
        // 格式符前加空格吃掉之前输入留在缓冲区的换行符
        scanf(" %[^\n]", n[i].name);
    }

    // 左对齐输出,表格更规整
    printf("%-10s %-10s %s\n", "Name", "Acc. no", "Balance");
    for(int i = 0; i < test_cnt; i++) {
        printf("%-10s %-10d %.2f\n", n[i].name, n[i].acNum, n[i].balance);
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Sahil Dadhwal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 01:57:04