C语言二进制转结构体后关联文本文件内容打印异常问题
问题与解决
问题描述
需要同时读取一个文本文件和一个二进制文件,两者内容行一一对应。使用fread将二进制文件内容读取到Registos_Binario结构体数组后,尝试在循环内打印结构体中的向量时,得到的内容与二进制文件实际内容不符。
原代码
typedef struct { int vetorInteiros[6]; char vetorCaracteres[6]; }Registos_Binario; int ler_informacao_total(char *FichLimpo, char *FichBinario, Registos_Binario *vetor_estruturas) { char classeChave[500][500]; char classesValor[500]; int comprimento_mapa = 0; FILE *fB = fopen(FichBinario, "rb"); if(fB == NULL) { printf("Nao foi possivel encontrar o ficheiro.\n"); return 1; } for(int i = 0; i < 345; i++) { fread(&vetor_estruturas[i].vetorInteiros, 6, 1, fB); fread(&vetor_estruturas[i].vetorCaracteres, 6, 1, fB); fseek(fB, 2, SEEK_CUR); } fclose(fB); return 0; // 补充缺失的返回值 } int main() { char escolha; char nomeficheirosujo[100]; char nomefhicheirolimpo[100]; char nomeficheirobinario[100]; Registos_Binario vetor_estruturas[345]; // 此处缺少调用ler_informacao_total、读取文本文件及打印逻辑 }
问题分析与修复方案
1. fread参数错误导致读取数据不完整
原代码中读取vetorInteiros的语句逻辑错误:fread的第二个参数是单个元素的字节大小,第三个参数是元素个数。vetorInteiros是int[6],每个int占4字节(多数平台),正确写法应该是读取6个int元素:
fread(vetor_estruturas[i].vetorInteiros, sizeof(int), 6, fB);
读取字符数组时,虽然char占1字节,写法可保留,但为统一规范建议写成:
fread(vetor_estruturas[i].vetorCaracteres, sizeof(char), 6, fB);
2. 结构体内存对齐问题
C语言结构体存在内存对齐机制,Registos_Binario中int[6]占24字节,char[6]占6字节,总大小可能因对齐被填充到32字节(比如对齐到8字节边界)。如果二进制文件是直接写入整个结构体,分开读取数组会导致数据错位,此时应直接读取整个结构体:
fread(&vetor_estruturas[i], sizeof(Registos_Binario), 1, fB);
之后再执行fseek(fB, 2, SEEK_CUR)(需确保二进制文件中每个结构体后确实有2字节额外数据)。
3. 补充文本文件读取与对应打印逻辑
需要打开文本文件逐行读取,再与对应二进制结构体信息一同打印,示例代码如下:
// 在ler_informacao_total函数中补充文本文件处理 FILE *fT = fopen(FichLimpo, "r"); if(fT == NULL) { printf("Nao foi possivel abrir o ficheiro de texto.\n"); fclose(fB); return 1; } char linha_texto[500]; for(int i = 0; i < 345; i++) { // 读取文本行 if(fgets(linha_texto, sizeof(linha_texto), fT) == NULL) break; // 读取二进制结构体(修复后的写法) fread(&vetor_estruturas[i], sizeof(Registos_Binario), 1, fB); fseek(fB, 2, SEEK_CUR); // 打印文本行和二进制数据 printf("Linha %d: %s", i+1, linha_texto); printf("Inteiros: "); for(int j = 0; j < 6; j++) { printf("%d ", vetor_estruturas[i].vetorInteiros[j]); } printf("\nCaracteres: %.*s\n", 6, vetor_estruturas[i].vetorCaracteres); } fclose(fT);
4. 其他细节修复
- 修正原代码中
printf的拼写错误:Nao fo possivel改为Nao foi possivel,并补充换行符\n。 - 给
ler_informacao_total函数补充缺失的返回值return 0;。 - 在
main函数中补充调用ler_informacao_total的逻辑,例如获取文件名后传入函数。
内容的提问来源于stack exchange,提问作者Dimmezy
相关产品推荐
相关产品推荐

