user-0 提问: 为什么fwrite写入的用fread读出再打印是乱码

回复:
user: user-1
content: 电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……   推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

user: user-0
content: 引用 2 楼 自信男孩的回复:#include<stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h>  typedef struct data { 	char xuehao[12]; 	char xingming[6]; 	int math; 	int wuli; 	int yuwen; 	int huaxue; }DA;  int main() { 	DA student[50]; 	DA student1[50]; 	int i=0; 	FILE *fp = fopen("D:\\zuoye\\stu.txt","r"); 	if (!fp) { 		fprintf(stderr, "Open file error: %s\n", strerror(errno)); 		exit(0); 	}  	while(!feof(fp)) 	{ 		fscanf(fp,"%s%s%d%d%d%d\n", 				student[i].xuehao, 				student[i].xingming, 				&student[i].math, 				&student[i].wuli, 				&student[i].yuwen, 				&student[i].huaxue); 		i++; 	} 	//打印信息  	for(i=0;i<30;i++) { 		printf("%s  %s  %d  %d  %d  %d\n", 				student[i].xuehao, 				student[i].xingming, 				student[i].math, 				student[i].wuli, 				student[i].yuwen, 				student[i].huaxue); 	} 	fclose(fp); 	FILE *fp1 = fopen("D:\\zuoye\\stu.dat","w"); 	if (!fp1) { 		fprintf(stderr, "Open file error: %s\n", strerror(errno)); 		exit(0); 	}  	/* 	for(i=0;i<30;i++) 		fwrite(&student[i], sizeof(DA), 1, fp1); 		*/ 	fwrite(student, sizeof(DA), 30, fp1); 	fclose(fp1);  	FILE *fp2 = fopen("D:\\zouye\\stu.dat","r"); 	if (!fp2) { 		fprintf(stderr, "Open file error: %s\n", strerror(errno)); 		exit(0); 	}  	for(i=0;i<30;i++) 	{ 		fread(&student1[i],sizeof(DA),1,fp2); 		printf("%s  %s  %d  %d  %d  %d\n", 				student1[i].xuehao, 				student1[i].xingming, 				student1[i].math, 				student1[i].wuli, 				student1[i].yuwen, 				student1[i].huaxue); 	}  	fclose(fp2); } 参考一下吧  有两个地方需要注意： 第一个地方，fscanf读，如果你的txt文件是每个学生信息占一行，那么fscanf读取时注意加'\n'； 第二个地方，也是主要的错误所在。fwrite没问题，一次性写了30个学生信息到文件中，但是读的时候有问题了，因为不是一次读30个学生信息，而是一次读一个学生信息，因此fread的第一个参数应该是&student1[i]，而不是student1. 建议自己思考一下fread的第一个参数应该是什么 我又写了一边读二进制形式的文本代码，发现一样的代码，新的代码可以读出，谢谢大神了

user: user-2
content: 建议对文件的打开做判断，并且使用strerror(errno)会对调试有很大的帮助

user: user-2
content: #include<stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h>  typedef struct data { 	char xuehao[12]; 	char xingming[6]; 	int math; 	int wuli; 	int yuwen; 	int huaxue; }DA;  int main() { 	DA student[50]; 	DA student1[50]; 	int i=0; 	FILE *fp = fopen("D:\\zuoye\\stu.txt","r"); 	if (!fp) { 		fprintf(stderr, "Open file error: %s\n", strerror(errno)); 		exit(0); 	}  	while(!feof(fp)) 	{ 		fscanf(fp,"%s%s%d%d%d%d\n", 				student[i].xuehao, 				student[i].xingming, 				&student[i].math, 				&student[i].wuli, 				&student[i].yuwen, 				&student[i].huaxue); 		i++; 	} 	//打印信息  	for(i=0;i<30;i++) { 		printf("%s  %s  %d  %d  %d  %d\n", 				student[i].xuehao, 				student[i].xingming, 				student[i].math, 				student[i].wuli, 				student[i].yuwen, 				student[i].huaxue); 	} 	fclose(fp); 	FILE *fp1 = fopen("D:\\zuoye\\stu.dat","w"); 	if (!fp1) { 		fprintf(stderr, "Open file error: %s\n", strerror(errno)); 		exit(0); 	}  	/* 	for(i=0;i<30;i++) 		fwrite(&student[i], sizeof(DA), 1, fp1); 		*/ 	fwrite(student, sizeof(DA), 30, fp1); 	fclose(fp1);  	FILE *fp2 = fopen("D:\\zouye\\stu.dat","r"); 	if (!fp2) { 		fprintf(stderr, "Open file error: %s\n", strerror(errno)); 		exit(0); 	}  	for(i=0;i<30;i++) 	{ 		fread(&student1[i],sizeof(DA),1,fp2); 		printf("%s  %s  %d  %d  %d  %d\n", 				student1[i].xuehao, 				student1[i].xingming, 				student1[i].math, 				student1[i].wuli, 				student1[i].yuwen, 				student1[i].huaxue); 	}  	fclose(fp2); } 参考一下吧  有两个地方需要注意： 第一个地方，fscanf读，如果你的txt文件是每个学生信息占一行，那么fscanf读取时注意加'\n'； 第二个地方，也是主要的错误所在。fwrite没问题，一次性写了30个学生信息到文件中，但是读的时候有问题了，因为不是一次读30个学生信息，而是一次读一个学生信息，因此fread的第一个参数应该是&student1[i]，而不是student1. 建议自己思考一下fread的第一个参数应该是什么

user: user-0
content: 求大神给解答，我很困扰啊。。。。。