C语言结构体写入TXT文件异常:整数字段显示乱码
结构体写入TXT文件grade字段乱码问题解决
问题描述
我尝试从TXT文件读取数据到struct para类型的结构体数组,再将数组中的部分数据写入另一个TXT文件。但输出文件中仅name字段显示正常,grade字段出现乱码(如ÌÌÌÌ...)。
原代码
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <ctype.h> #define MAX 5 // max array size //C:\Users\PATOX\Desktop\uczniowie.txt struct para { char name[15]; int grade; }; int read(FILE* file, struct para tab[], int m, int *k) { FILE* output; char path[80]; printf("Enter input file path: "); scanf_s("%s", path, 80); file = fopen(path, "r"); if (file == NULL) { printf("\nError opening input file\n"); return 1; } else { char path[80]; printf("Enter output file path: "); scanf_s("%s", path, 80); output = fopen(path, "w"); if (output == NULL) { printf("\nError opening output file\n"); return 1; } for (int i = 0; i < m; i++) { if (!feof(file)) { int index; char name[15]; int grade; fscanf(file, "%d %s %d", &index, name, &grade); strcpy(tab[i].name, name); tab[i].grade = grade; fwrite(&(tab[i]), sizeof(struct para), 1, output); (*k)++; } } } fclose(file); fclose(output); return 0; } void print_array(struct para tab[], int m) { for (int i = 0; i < m; i++) { printf("%s %d\n", tab[i].name, tab[i].grade); } } int main() { int k = 0; //data counter FILE* file; struct para tab[5]; read(&file, tab, MAX, &k); print_array(tab, k); return 0; }
预期输出(output.txt)
Drozd 4 Jas 5 Tom 6 Bas 8
实际输出(output.txt)
Drozd ÌÌÌÌÌÌÌÌÌÌ Jas ÌÌÌÌÌÌÌÌÌÌÌÌ Tom ÌÌÌÌÌÌÌÌÌÌÌÌ Bas ÌÌÌÌÌÌÌÌÌÌÌÌ
问题原因
- 写入方式错误:你用
fwrite以二进制方式写入结构体,而你需要的是文本格式输出。fwrite会直接将结构体的内存字节原样写入文件:name字段是char数组,本身就是文本字节,所以能正常显示;grade是int类型,数值的二进制存储(比如4对应0x00000004)会被文本编辑器当作ASCII字符解析,从而出现乱码。
- 循环逻辑隐患:用
feof作为循环判断条件容易导致多读一次数据。
解决方案
1. 替换写入方式为文本格式化输出
把fwrite改为fprintf,像控制台打印那样格式化写入每个字段:
// 替换原有的fwrite语句 fprintf(output_file, "%s %d ", tab[i].name, tab[i].grade);
2. 修正循环逻辑与参数冗余
- 去掉
read函数中冗余的FILE* file参数(函数内重新赋值不会影响外部变量); - 用
fscanf的返回值判断读取是否成功,避免feof的问题。
修正后的完整代码
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <ctype.h> #define MAX 5 // max array size struct para { char name[15]; int grade; }; int read(struct para tab[], int m, int *k) { FILE* input_file; FILE* output_file; char path[80]; printf("Enter input file path: "); scanf_s("%s", path, 80); input_file = fopen(path, "r"); if (input_file == NULL) { printf("\nError opening input file\n"); return 1; } char output_path[80]; printf("Enter output file path: "); scanf_s("%s", output_path, 80); output_file = fopen(output_path, "w"); if (output_file == NULL) { printf("\nError opening output file\n"); fclose(input_file); return 1; } int i = 0; int index; char name[15]; int grade; // 用fscanf返回值判断是否成功读取3个字段 while (i < m && fscanf(input_file, "%d %s %d", &index, name, &grade) == 3) { strcpy(tab[i].name, name); tab[i].grade = grade; fprintf(output_file, "%s %d ", tab[i].name, tab[i].grade); (*k)++; i++; } fclose(input_file); fclose(output_file); return 0; } void print_array(struct para tab[], int m) { for (int i = 0; i < m; i++) { printf("%s %d\n", tab[i].name, tab[i].grade); } } int main() { int k = 0; //data counter struct para tab[5]; read(tab, MAX, &k); print_array(tab, k); return 0; }
内容的提问来源于stack exchange,提问作者Veanty
相关产品推荐
相关产品推荐

