使用C语言fread读取结构体时输出异常问题求助
结构体二进制读写后字符串字段内容混淆的原因与解决方法
你遇到的问题是典型的C语言字符串终止符缺失导致的输出越界问题,咱们一步步拆解原因和解决办法:
问题根源分析
字符串终止符('\0')缺失
C语言中,字符串必须以'\0'作为结束标记,printf("%s")会一直读取内存直到遇到'\0'才停止。你的结构体里:idNo[11]和tel[11]的长度刚好等于输入的字符数(11位),写入文件时数组被完全填满,没有多余空间存放'\0'。- 读取二进制数据时,
fread只是原样读取内存内容,不会自动补充'\0',所以idNo和tel字段没有结束标记,printf会继续读取后面的tel、email字段内容,直到找到某个'\0'为止。
代码拼写错误
你的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
相关产品推荐
相关产品推荐

