关于fwrite,fread函数问题,最后怎么好像多东西了。。
呃,伸手党再次现身了。。。。我定义了一个用于创建链表结点的数组,创建链表以后,用fwrite存入一个文件,然后fread读取该文件重新构建链表。问题来了,(文件是二进制文件,文本文件也行)在存入时还是比较顺利的,但是在读取的时候运行流程出现问题:(我感觉文件已经结束了呀,为什么没有结束)
// 函数名称:Load
// 函数作用:根据文件名载入一个二进制文件数据并建立链表,返回链表头指针
// 创建时间:2014年3月27日21:38:12
// 返回值类型:DATA *
// 形式参数:char *
DATA *Load(char *fileName)
{
FILE *fp = NULL;
DATA *head = NULL;
DATA temp;
DATA *pt = &temp;
DATA *p1 = NULL;
DATA *p2 = NULL;
//int i = 1;
if (NULL == (fp = fopen(fileName, "rb")))
{
printf("文件%s打开失败。\n", fileName);
fclose(fp);
return(NULL);
}
if (fread(pt, LEN, 1, fp) != 1)
{
printf("文件%s读取失败。\n", fileName);
fclose(fp);
return(NULL);
}
for (; feof(fp) == 0;) // 读取最后一个结点(尾结点)后,feof(fp)还是不等于0,然后会再进行一次for循环,就进行if(fread)下面的else分支
{
p1 = (DATA *)malloc(LEN);
*p1 = temp;
//printf("第%d个结点存入。\n", i++);
if (NULL == head)
{
head = p1;
}
else
{
p2->next = p1;
}
p2 = p1;
if (fread(pt, LEN, 1, fp) != 1)
{
if (feof(fp) == 1)
{
printf("文件%s读取结束。\n", fileName);
}
else
{
printf("文件%s读取失败。\n", fileName);
printf("%-6d%-6s%-6d\n", pt->num, pt->name, pt->score);
}
}
}
fclose(fp);
printf("文件%s数据读取成功,已建立链表。\n", fileName);
return(head);
}
程序还有很多问题,呃大牛清喷,如果能给些建议感激不尽!~ 呃这不是这帖子主题啦
这是前面的定义:
#define LEN sizeof(DATA)
typedef struct abc
{
int num;
char name[10];
int score;
struct abc *next;
}DATA;
发一下全部函数,有点长,Save函数还有Creat函数都在里面。
程序代码:
/*由于生疏,所以复习一下链表,包括创建,增加,删除,排序,以及文件的读取和存储*/ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #define LEN sizeof(DATA) typedef struct abc { int num; char name[10]; int score; struct abc *next; }DATA; // 函数名称:Creat // 函数作用:建立链表 // 创建时间:2014年3月21日0:07:02 // 返回值类型:DATA * // 形式参数:void DATA *Creat(void) { int temp = 0; DATA *p1 = NULL; DATA *p2 = NULL; DATA *head = NULL; printf("请输入数据:(当号码为0时输入结束)\n"); printf("请输入号码:\n"); scanf("%d", &temp); for (; temp != 0;) { p1 = (DATA *)malloc(LEN); p1->num = temp; printf("请输入名字和分数:\n"); scanf("%s%d", p1->name, &p1->score); if (NULL == head) { head = p1; } else { p2->next = p1; } p2 = p1; printf("请输入号码:\n"); scanf("%d", &temp); } p2->next = NULL; printf("链表已成功创建。\n"); return(head); } // 函数名称:Print // 函数作用:输出链表 // 创建时间:2014年3月21日0:20:13 // 返回值类型:void // 形式参数: DATA * void Print(DATA *head) { DATA *p = head; if (p == NULL) { printf("链表为空。\n"); } else { printf("Num Name Score\n"); for(; p != NULL;) { printf("%-6d%-6s%-6d\n", p->num, p->name, p->score); p = p->next; } } printf("链表数据已输出。\n"); } // 函数名称:Delete // 函数作用:根据形参删除该序号某结点(链表数据都不一样) // 创建时间:2014年3月21日0:28:50 // 返回值类型:DATA * // 形式参数:DATA *, int DATA *Delete(DATA *head, int temp) { DATA *p1 = head; DATA *p2 = NULL; if (NULL == p1) { printf("链表为空,无数据。\n"); } else { for (p2 = p1; (p1 != NULL)&&(p1->num != temp);) { p2 = p1; p1 = p1->next; } if (NULL == p1) { printf("链表无该数据。\n"); } else { if (p1 == head) { head = p1->next; } else { p2->next = p1->next; } free(p1); p1 = NULL; printf("数据编号为%d的结点已经从链表中删除。\n", temp); } } return(head); } // 函数名称:DeleteName // 函数作用:删除链表中具有该名字的结点(可能有多个) // 创建时间:2014年3月21日1:04:20 // 返回值类型:DATA * // 形式参数:DATA *, char * DATA *DeleteName(DATA *head, char *temp) { DATA *p1 = head; DATA *p2 = head; DATA *p3 = head; if (NULL == p1) { printf("链表为空,无数据。\n"); } else { for(; p2 != NULL;) { if (strcmp(p2->name, temp) == 0) { if (p2 == p1) { p1 = p1->next; free(p2); p2 = p1; p3 = p2; } else { p3->next = p2->next; free(p2); p2 = p3->next; } printf("数据名称为%s的结点已经从链表中删除。\n", temp); }// end if else { if (p2 == p1) { p2 = p2->next; } else { p3 = p2; p2 = p2->next; } }// end else }// end for printf("链表已经排查完毕。\n"); } return(p1); } // 函数名称:Insert // 函数作用:根据结点score由小到大插入一个节点数据 // 创建时间:2014年3月21日1:57:53 // 返回值类型:DATA * // 形式参数:DATA *, DATA * DATA *Insert(DATA *head, DATA *temp) { DATA *p1 = head; DATA *p2 = head; if (NULL == head) { head = temp; temp->next = NULL; } else { for (; (p1->score < temp->score) && (p1->next != NULL);) { p2 = p1; p1 = p1->next; } if (p1->score > temp->score) { if (p1 == head) { head = temp; } else { p2->next = temp; } temp->next = p1; } else { p1->next = temp; temp->next = NULL; } } printf("数据已插入。\n"); return(head); } // 函数名称:Sort // 函数作用:按照score从小到大排序 // 创建时间:2014年3月21日3:02:55 // 返回值类型:void // 形式参数:DATA * void Sort(DATA *head) { DATA temp; DATA *p1 = head; DATA *p2 = NULL; DATA *p3 = &temp; if (NULL == p1) { printf("链表为空,无数据。\n"); } else { for (; p1->next != NULL;) { p2 = p1->next; for (; p2 != NULL;) { if (p2->score < p1->score) { p3->num = p1->num; p1->num = p2->num; p2->num = p3->num; p3->score = p1->score; p1->score = p2->score; p2->score = p3->score; strcpy(p3->name, p1->name); strcpy(p1->name, p2->name); strcpy(p2->name, p3->name); } p2 = p2->next; }// end for p1 = p1->next; }// end for printf("链表已经排序。\n"); }// end else } // 函数名称:SortOpp // 函数作用:将链表倒序排列 // 创建时间:2014年3月21日8:32:12 // 返回值类型:DATA * // 形式参数:DATA * DATA *SortOpp(DATA *head) { DATA *p1 = head; DATA *p2 = NULL; DATA *p3 = NULL; if (NULL == p1) { printf("链表为空,无数据。\n"); return(p1); } else if (NULL == p1->next) { printf("链表已倒序排列。\n"); return(p1); } else { p2 = p1->next; p3 = p2->next; p1->next = NULL; p2->next = p1; for (; p3 != NULL;) { p1 = p2; p2 = p3; p3 = p3->next; p2->next = p1; } printf("链表已倒序排列。\n"); return(p2); } } // 函数名称:Load // 函数作用:根据文件名载入一个二进制文件数据并建立链表,返回链表头指针 // 创建时间:2014年3月27日21:38:12 // 返回值类型:DATA * // 形式参数:char * DATA *Load(char *fileName) { FILE *fp = NULL; DATA *head = NULL; DATA temp; DATA *pt = &temp; DATA *p1 = NULL; DATA *p2 = NULL; int i = 1; if (NULL == (fp = fopen(fileName, "rb"))) { printf("文件%s打开失败。\n", fileName); fclose(fp); return(NULL); } if (fread(pt, LEN, 1, fp) != 1) { printf("文件%s读取失败。\n", fileName); fclose(fp); return(NULL); } for (; feof(fp) == 0;) // 读取最后一个结点(尾结点)后,feof(fp)还是不等于0,然后就读取失败 { p1 = (DATA *)malloc(LEN); *p1 = temp; printf("第%d个结点存入。\n", i++); if (NULL == head) { head = p1; } else { p2->next = p1; } p2 = p1; if (fread(pt, LEN, 1, fp) != 1) { if (feof(fp) == 1) { printf("文件%s读取结束。\n", fileName); } else { printf("文件%s读取失败。\n", fileName); printf("%-6d%-6s%-6d\n", pt->num, pt->name, pt->score); } } } fclose(fp); printf("文件%s数据读取成功,已建立链表。\n", fileName); return(head); } // 函数名称:LoadAscii // 函数作用:根据文件名载入一个文本文件数据并建立链表,返回链表头指针 // 创建时间:2014年3月27日21:38:12 // 返回值类型:DATA * // 形式参数:char * DATA *LoadAscii(char *fileName) { FILE *fp = NULL; DATA *head = NULL; DATA temp; DATA *pt = &temp; DATA *p1 = NULL; DATA *p2 = NULL; if (NULL == (fp = fopen(fileName, "r"))) { printf("文件%s打开失败。\n", fileName); fclose(fp); return(NULL); } if (fread(pt, LEN, 1, fp) != 1) { printf("文件%s读取失败。\n", fileName); fclose(fp); return(NULL); } for (; feof(fp) == 0;) { p1 = (DATA *)malloc(LEN); *p1 = temp; if (NULL == head) { head = p1; } else { p2->next = p1; } p2 = p1; if (fread(pt, LEN, 1, fp) != 1) { if (feof(fp) == 1) { printf("文件%s读取结束。\n", fileName); } else { printf("文件%s读取失败。\n", fileName); //printf("%-6d%-6s%-6d\n", pt->num, pt->name, pt->score); } } } fclose(fp); printf("文件%s数据读取成功,已建立链表。\n", fileName); return(head); } // 函数名称:Save // 函数作用:把该头指针指向的链表数据依次存入该名称的二进制文件中 // 创建时间:2014年3月27日22:14:33 // 返回值类型:void // 形式参数:DATA *, char * void Save(DATA *head, char *fileName) { FILE *fp = NULL; DATA *p = head; printf("数据开始存入:\n"); if (NULL == (fp = fopen(fileName, "wb"))) { printf("文件%s打开失败。\n", fileName); return; } for(;p != NULL;) { if (fwrite(p, LEN, 1, fp) != 1) { printf("数据写入失败。\n"); } p = p->next; } fclose(fp); printf("链表数据存入文件%s成功\n", fileName); } // 函数名称:SaveAscii // 函数作用:把该头指针指向的链表数据依次存入该名称的文本文件中 // 创建时间:2014年3月27日22:14:33 // 返回值类型:void // 形式参数:DATA *, char * void SaveAscii(DATA *head, char *fileName) { FILE *fp = NULL; DATA *p = head; printf("数据开始存入:\n"); if (NULL == (fp = fopen(fileName, "w"))) { printf("文件%s打开失败。\n", fileName); return; } for(;p != NULL;) { if (fwrite(p, LEN, 1, fp) != 1) { printf("数据写入失败。\n"); } p = p->next; } fclose(fp); printf("链表数据存入文件%s成功\n", fileName); } // 函数名称:main // 函数作用:调用各被调函数,验证能否运行成功。 // 创建时间:2014年3月27日22:29:10 void main() { char *fileName = "example.txt"; char *a = "sort"; DATA *head; DATA temp = {3, "sun", 3}; DATA *p = &temp; //head = Creat(); //Print(head); //Save(head, fileName); head = Load(a); Print(head); //Save(head, a); //head = SortOpp(head); //Print(head); //Sort(head); //Print(head); //head = SortOpp(head); //Print(head); //head = Delete(head, 2); //Print(head); //head = DeleteName(head, "yang"); //Print(head); //head = Insert(head, p); //Print(head); }