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

使用C语言fread读取结构体时输出异常问题求助

结构体二进制读写后字符串字段内容混淆的原因与解决方法

你遇到的问题是典型的C语言字符串终止符缺失导致的输出越界问题,咱们一步步拆解原因和解决办法:

问题根源分析

  1. 字符串终止符('\0')缺失
    C语言中,字符串必须以'\0'作为结束标记,printf("%s")会一直读取内存直到遇到'\0'才停止。你的结构体里:

    • idNo[11]和tel[11]的长度刚好等于输入的字符数(11位),写入文件时数组被完全填满,没有多余空间存放'\0'。
    • 读取二进制数据时,fread只是原样读取内存内容,不会自动补充'\0',所以idNo和tel字段没有结束标记,printf会继续读取后面的tel、email字段内容,直到找到某个'\0'为止。
  2. 代码拼写错误
    你的printf语句里写错了字段名:personelBilgi.addres应该是personelBilgi.address,这会导致读取错误的内存区域,虽然不是当前串内容的主因,但也需要修正。

解决办法

方法1:调整结构体字段长度,预留终止符空间

把需要存储固定长度字符串的数组长度加1,给'\0'留位置:

typedef struct {
    char name[100];
    char surname[100];
    char idNo[12];  // 原11→12,存11位ID+1位'\0'
    char tel[12];   // 原11→12,存11位电话+1位'\0'
    char address[200];
    char email[100];
} personel;

方法2:读写时手动添加终止符

如果不想修改结构体,就在写入和读取时手动给字符串字段添加'\0':

写入时(假设你有写入函数):

当获取用户输入后,用strncpy复制字符串并手动补终止符:

// 示例:处理ID输入
strncpy(personelBilgi.idNo, inputId, 10);  // 只复制前10个字符,留位置给'\0'
personelBilgi.idNo[10] = '\0';

// 处理电话同理
strncpy(personelBilgi.tel, inputTel, 10);
personelBilgi.tel[10] = '\0';

读取时(修改你的personelListele函数):

在读取结构体后,给每个字符串字段强制添加终止符:

void personelListele(){
    FILE *pdosya;
    personel personelBilgi;
    pdosya = fopen("personel.txt","rb");
    if(pdosya==NULL){
        printf("personel.txt dosyasını açamadım");
        exit(1);
    }
    int c;
    while((c = fread(&personelBilgi,sizeof(personel),1,pdosya)) != 0) {
        // 手动添加终止符,确保字符串正常结束
        personelBilgi.name[99] = '\0';
        personelBilgi.surname[99] = '\0';
        personelBilgi.idNo[10] = '\0';
        personelBilgi.tel[10] = '\0';
        personelBilgi.address[199] = '\0';
        personelBilgi.email[99] = '\0';

        // 修正拼写错误:addres → address
        printf("Name= %s\n",personelBilgi.name);
        printf("Surname= %s\n",personelBilgi.surname);
        printf("id = %s\n",personelBilgi.idNo);
        printf("Tel = %s\n",personelBilgi.tel);
        printf("Address = %s\n",personelBilgi.address);
        printf("Email = %s\n",personelBilgi.email);
    }
    fclose(pdosya);  // 别忘了关闭文件,避免资源泄漏
}

额外注意事项

  • 一定要记得关闭文件,你的原代码里没有fclose(pdosya),这会导致资源泄漏。
  • 输入处理时,避免使用gets这类不安全的函数,建议用fgets配合strtok或者带长度限制的scanf来获取用户输入,防止缓冲区溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:05:49