user-0 提问: C语言文件操作中的问题，关于fread和fwrite

回复:
user: user-1
content: 引用 楼主 sz0hj 的回复:我想把链表保存进文件，之后从这个文件读出每个节点，用这些新建立一个链表，应该怎么办呢？ 谢谢~~~  一个简单的方法是，只保存节点地址（节点指针）以外的数据。 每次读文件中的数据，并用这些数据创建链表。 必要的时候，可以保存数据个数。  指针保存到文件中，丝毫作用也不起。

user: user-2
content: 本来说帮你调调吧  结果 我也郁闷了；为什么 能正确写入  却不能读出来 ，谁能帮我看看阿  ！  #include<stdio.h> #include<stdlib.h> #define LEN sizeof(struct student) struct student {    		int NO; 		char name[30]; 		float achievement[6]; 		float aver; 		float sum; 		struct student* next; }; struct student *input(int a,int b) { 		int i=0,r; 		struct student *p1,*p2,*head; //		head=(struct student*)malloc(LEN); 		while(i<a) 		{ 				p1=(struct student*)malloc(LEN); 				p1->next=NULL; 				i=i+1; 				p1->sum=0; 				printf("请输入学号：姓名：\n"); 				scanf("%d %s",&p1->NO,p1->name); 				for(r=0;r<b;r++) 				{    						printf("请输入第%d门成绩：\n",r+1); 						scanf("%f",&p1->achievement[r]); 						p1->sum=p1->sum+p1->achievement[r]; 				} 				p1->aver=p1->sum/b; 				if(1==i){ 						head = p1; 						head->next = NULL; 				}else{ 						p1->next = head; 						head = p1; 				}  		} 		return head; } void save(int a,struct student*head) { 		printf("请输入文件名：例[D:\\string.dat]\n"); 		char m[30]; 		scanf("%s",m); 		struct student*p1,*p2; 		int    r=1; 		p1=p2=(struct student*)malloc(LEN); 		FILE*fp; 		fp=fopen(m,"w"); //		fwrite(head,LEN,1,fp);                                  //这里是写入文件。 		fwrite(&head->NO,4,1,fp);                                  //这里是写入文件。 		fwrite(head->name,1,5,fp);                                  //这里是写入文件。 		while(r<a) 		{ 				r=r+1; 				p2->next=p1; 				p2=p1; 				p1=(struct student*)malloc(LEN); 				fwrite(p1,LEN,1,fp); 		} 		close(fp); } struct student* output(int a)                                                {    		struct student*head; 		struct student*p1,*p2; 		head=p1=p2=(struct student*)malloc(LEN); 		FILE *fp1;    		char m[30]; 		int NO,n; 		char buf[5]={}; 		printf("输入 文件名 m\n"); 		scanf("%s",m); 		printf("m = %s\n",m); 		if((fp1=fopen(m,"r"))==NULL)                		{    				printf("can not be open!\n"); 				exit(0); 		} 		int    r=0; 		printf("a= %d\n",a); 		while(r<a) 		{ 				r=r+1; 				n = fread(&NO,4,1,fp1);   				printf("n1 = %d\n",n);   				printf("%d\n",NO);       				n = fread(buf,1,5,fp1);   				printf("n2  = %d\n",n);    				printf("%s\n",buf);      				printf("why  ???\n");       //将读出的结构体里面的数据输 出到屏幕，可是结果不对，乱码的。 		} 		fclose(fp1); 		return(head); } void main() { 		struct student *head,*p; 		head=NULL; 		int a,b; 		printf("输入 学生数 和 课程数\n"); 		scanf("%d %d",&a,&b); 		head=input(a,b); 		save(a,head); 		for(p=head;p!=NULL;p=p->next){ 				printf("%d %s\n",p->NO,p->name); 		}  		output(a); }

user: user-3
content: 你的程序我跑了，结果显示正常的，只是打开文件看的时候显示的是乱码，因为写入的时候以二进制形式写入，所以单独看是乱码的，

user: user-3
content: 单独检验fwrite函数，只有写char[] 类型才成功，其他的都失败了，不知道为啥，，，

user: user-4
content: "w"，“r"改成"wb","rb"

user: user-5
content: void save(int a,struct student*head)函数里没有对打开的文件关闭哦。

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

user: user-7
content: 引用 楼主 sz0hj 的回复:#include<stdio.h> #include<stdlib.h> #define LEN sizeof(struct student) struct student {	 	long int NO; 	char name[30]; 	float achievement[6]; 	float aver; 	float sum; 	struct student*next; }; struct student*input(int a,int b) { 	int i=0,r; 	struct student*p1,*p2,*head; 	head=p1=p2=(struct student*)malloc(LEN); 	while(i<a) 	{ 		i=i+1; 		p1->sum=0; 		printf("请输入学号：姓名：\n"); 		scanf("%d%s",&p1->NO,&p1->name); 		for(r=0;r<b;r++) 		{	 			printf("请输入第%d门成绩：\n",r+1); 			scanf("%f",&p1->achievement[r]); 			p1->sum=p1->sum+p1->achievement[r]; 		} 		p1->aver=p1->sum/b; 		if(i==1) 		{ 			head=p1; 		} 		p2=p1; 		p1=(struct student*)malloc(LEN); 		p2->next=p1; 	} 	p2->next=NULL; 	return head; } void save(int a,struct student*head) { 	printf("请输入文件名：例[D:\\string.dat]\n"); 	char m[30]; 	scanf("%s",m); 	struct student*p1,*p2; 	int	r=1; 	p1=p2=(struct student*)malloc(LEN); 	FILE*fp; 	fp=fopen(m,"w"); 	fwrite(head,LEN,1,fp);                                  //这里是写入文件。 	while(r<a) 	{ 		r=r+1; 		p2->next=p1; 		p2=p1; 		p1=(struct student*)malloc(LEN); 		fwrite(p1,LEN,1,fp); 	} 	p2->next=NULL; } struct student*input(int a)												 {	 	struct student*head; 	struct student*p1,*p2; 	head=p1=p2=(struct student*)malloc(LEN); 	FILE*f1;	 	char m[30]; 	scanf("%s",m); 	if((f1=fopen(m,"r"))==NULL)				 	{	 		printf("can not be open!\n"); 		exit(0); 	} 	int	r=0; 	while(r<a) 	{ 		r=r+1; 		fread(p1,LEN,1,f1);                                          //这里从文件里面读出。 		printf("%d\t%s\n\n",p1->NO,p1->name);       //将读出的结构体里面的数据输 出到屏幕，可是结果不对，乱码的。 	} 	return(head); 	fclose(f1); } void main() { 	struct student*head; 	head=NULL; 	int a,b; 	scanf("%d%d",&a,&b); 	head=input(a,b); 	save(a,head); 	input(a); } 为什么输出的时候就是乱码的呢？ 哪里有问题？ 我想把链表保存进文件，之后从这个文件读出每个节点，用这些新建立一个链表，应该怎么办呢？ 谢谢~~~ 说个无关紧要的，为什么链表里没有first节点。。。。。。

user: user-1
content: 你的程序有以下几个问题  1）链表保存，不必保存指针。因为文件中保存指针，读取的时候，也用不到。  2）链表读出，要重新为链表的节点分配内存，即重建链表。  3）b要小于6 这个，不然就会出错，    所以：       要断言，并且要保护 4）分配的内存要释放。  5）保存数据，不需要分配内存。 6）保存的数据，不在链表中，没有保存链表中的数据。     7）输入是有内存泄露，     p2->next=NULL;    应该是 p1->next=NULL;  以上是错误  8）学生信息，没有必要和节点定义成一个结构体。    单独定义学生信息；    节点内有一个学生信息的成员，就可以了。 这个是，处理方式不太好。

user: user-8
content: 错误的地方有点多，结果不正确是正常的，lz可以先确定下input函数有没有问题

user: user-9
content: 19 error(s), 17 warning(s)

user: user-0
content: 大神们你们人呢？？  要死掉了，为什么啊。。。