![]() |
#2
々NARUTO2013-04-20 14:04
|
重新看完C后不久 写了个学生管理系统 ,这个系统 前天写的 还没写完 就遇到了些问题 !
其他的 函数都正常 主要是那个loadfile载入文件那块 出错了
刚开始 可发现 loadfile中那个fread函数 会不听的 读取 后来加了个 getlength函数求出 数据长度 给读取 做个限制
可发现 他妹的 刚开始 存进去的getlength的 结果为3读取的 时候 他妹的为0
反正 主要看Loadfile那个函数 ,那个函数错了 ,不晓得是为什么 求解答

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//设置个全局变量 用于在不同选择不同层次时显示不同的菜单
//定义一个 OBJ结构体 用于表示学生科目成绩
typedef struct OBJ
{
float math;
float english;
float chinese;
}OBJ,* POBJ;
//定义一个 STU结构体 用于表示学生的信息
typedef struct STUDENT
{
int number; //学号
char name[40]; //姓名
char sex; //性别
OBJ object; //科目
struct STUDENT* pNext; //指向下一个
}STU,* PSTU;
PSTU Create(); //创建学生的数据
FILE* OpenFile(char Get_Choose,char* filename); //新建 打开 文件的函数
PSTU LoadFile(FILE* file,PSTU pHead); //读取文件
void SaveFile(FILE* file,PSTU pHead); //保存文件 第一个参数为要保存到哪个文件 第二个为要保存的数据
void View(PSTU pHead); //浏览学生信息
void Sort(PSTU pHead); //排序
void CopyData(PSTU p1,const PSTU p2); //复制数据 将P2的值复制进P1中 不过指向的pNext不变
bool Find(PSTU pHead); //查找学生信息
bool Insert(PSTU pHead,int pos); //插入学生信息 第一个参数是要插入的头节点所指向的链表结构 第二个是要插入的位置
bool Delete(PSTU pHead,int pos); //删除学生信息 从第几个位置开始删除pos个位置的学生信息
int GetLength(PSTU); //得到链表长度
//PSTU CleanUpList(PSTU pHead); //清空链表中的数据
/*
各函数 调用测试.........................
*/
int main()
{
FILE* file=NULL;
PSTU pHead=NULL;
char filename[40]="123";
/*各函数 调用测试 均正常 就看 LoadFile那*/
file=OpenFile('n',filename);
pHead=Create();
View(pHead);
Sort(pHead);
View(pHead);
Delete(pHead,0);
View(pHead);
Find(pHead);
Insert(pHead,0);
View(pHead);
SaveFile(file,pHead);
fclose(file);
printf("continue 任意键\n");
getchar();
file=OpenFile('o',filename);
if (NULL==file)
{
fprintf(stderr,"文件打开失败");
exit(1);
}
rewind(file);
pHead=LoadFile(file,pHead); //////////////////就是在这出了问题
if(!pHead)
printf("载入 文件失败!\n");
View(pHead);
if (file!=NULL)
{
fclose(file);
}
return 0;
}
/*
函数调用测试
*/
FILE* OpenFile(char Get_Choose,char* filename)
{
FILE* file=NULL;
Get_Choose=toupper(Get_Choose);
strcat(filename,".dat"); //加入后缀名.dat
char mode[4];
if ('N'==Get_Choose)
{
strcpy(mode,"wb+");
}
else if ('O'==Get_Choose)
{
strcpy(mode,"rb+");
}
else
{
return NULL;
}
file = fopen(filename,mode);
return file;
}
PSTU Create()
{
PSTU pHead=NULL;
PSTU p=NULL,pNew=NULL;
int n=0; //要创建的个数
int number; //学号
float grade=0.0f; //保存成绩
char name[40]; //姓名
char sex; //性别
pHead=(PSTU)malloc(sizeof(STU)); //创建头结点
pHead->pNext=NULL;
p=pHead;
printf("请输入您要创建的学生信息个数:");
scanf("%d",&n);
for (int index=0;index<n;index++)
{
pNew=(PSTU)malloc(sizeof(STU));
printf("请输入第%d个学生学号:",index+1);
scanf("%d",&number);
pNew->number=number;
printf("请输入第%d个学生姓名:",index+1);
scanf("%s",name);
while(getchar()!='\n')
continue;
strcpy(pNew->name,name);
INPUT_ERROR_B:
printf("请输入第%d个学生性别 男(B)女(G)",index+1);
scanf("%c",&sex);
sex=toupper(sex);
if (sex!='B'&&sex!='G')
{
printf("输入错误,请重新输入\n");
goto INPUT_ERROR_B;
}
pNew->sex=sex;
printf("请输入第%d个学生的数学成绩:",index+1);
scanf("%f",&grade);
pNew->object.math=grade;
printf("请输入第%d个学生的英语成绩:",index+1);
scanf("%f",&grade);
pNew->object.english=grade;
printf("请输入第%d个学生的语文成绩:",index+1);
scanf("%f",&grade);
while(getchar()!='\n')
continue;
pNew->object.chinese=grade;
p->pNext=pNew;
p=p->pNext;
pNew->pNext=NULL;
}
return pHead;
}
PSTU LoadFile(FILE* file,PSTU pHead) //主要是这个函数的问题
{
PSTU p=NULL;
PSTU pSave=NULL;
int index=0;
int length=0;
fread(&length,sizeof(int),1,file); //这里读取后 为什么为0?
if (NULL==file||0==length)
{
return NULL;
}
if (NULL!=pHead)
{
for (p=pHead,index=0;p!=NULL;p=pSave)
{
pSave=p->pNext;
free(p);
}
}
pHead=(PSTU)malloc(sizeof(STU));
p=pHead;
p->pNext=NULL;
PSTU pNew=(PSTU)malloc(sizeof(STU));
pNew->pNext=NULL;
index=0;
while(fread(pNew,sizeof(STU),1,file),pNew!=NULL&&length<3)
{
index++;
p->pNext=pNew;
pNew=(PSTU)malloc(sizeof(STU));
p=pNew;
}
return pHead;
}
void SaveFile(FILE* file,PSTU pHead)
{
PSTU p;
int length=0;
if (file!=NULL)
{
length=GetLength(pHead->pNext);
fwrite(&length,sizeof(int),1,file);
for (p=pHead->pNext;p!=NULL;p=p->pNext)
{
fwrite(p,sizeof(STU),1,file);
}
fflush(file);
}
return;
}
void View(PSTU pHead)
{
float sum;
if (NULL==pHead->pNext)
{
printf("数据为空,无法浏览\n");
return;
}
PSTU p=pHead->pNext;
while(p!=NULL)
{
sum=p->object.math+p->object.english+p->object.chinese;
printf("\n学号:%d 姓名:%s 性别:%s\n",p->number,p->name,p->sex=='B'?"男":"女");
printf("数学:%.1f 英语%.1f 语文%.1f\n",p->object.math,p->object.english,p->object.chinese);
printf("总分:%.1f 平均分:%.1f\n\n",sum,sum/3);
p=p->pNext;
}
return;
}
void Sort(PSTU pHead)
{
char ch;
PSTU p;
PSTU q;
PSTU y=(PSTU)malloc(sizeof(STU));
float p_sum,q_sum;
INPUT_ERROR_C:
printf("请问您要按 总成绩(P) 学号(X):");
ch=getchar();
while(getchar()!='\n')
continue;
ch=toupper(ch);
if (ch!='X'&&ch!='P')
{
printf("输入错误,请重新输入\n");
goto INPUT_ERROR_C;
}
if ('X'==ch)
{
for (p=pHead->pNext;p!=NULL;p=p->pNext)
{
for (q=p->pNext;q!=NULL;q=q->pNext)
{
if((p->number)>(q->number))
{
CopyData(y,p);
CopyData(p,q);
CopyData(q,y);
}
}
}
}
else
{
for (p=pHead->pNext;p!=NULL;p=p->pNext)
{
for (q=p->pNext;q!=NULL;q=q->pNext)
{
p_sum=p->object.math+p->object.english+p->object.chinese;
q_sum=q->object.math+q->object.english+q->object.chinese;
if(p_sum<=q_sum)
{
CopyData(y,p);
CopyData(p,q);
CopyData(q,y);
}
}
}
}
return;
}
void CopyData(PSTU p1,const PSTU p2) //复制数据 pNext不变
{
PSTU pNext;
pNext=p1->pNext;
*p1=*p2;
p1->pNext=pNext;
return;
}
bool Find(PSTU pHead) //查找
{
bool isHave=false;
PSTU p=pHead;
char ch;
char name[40];
int number;
char sex;
float sum;
INPUT_ERROR_D:
printf("查找方式\n学号(X) 姓名(N) 性别(S)\n");
ch=getchar();
while(getchar()!='\n')
continue;
ch=toupper(ch);
if ('X'==ch)
{
printf("学号:");
scanf("%d",&number);
}
else if ('N'==ch)
{
printf("姓名:");
scanf("%s",name);
}
else if ('S'==ch)
{
printf("性别 男(B) 女(G):");
sex=getchar();
sex=toupper(sex);
}
else
{
printf("输如错误,请重新输入\n");
goto INPUT_ERROR_D;
}
while(getchar()!='\n')
continue;
for (p=pHead->pNext;p!=NULL;p=p->pNext)
{
sum=p->object.math+p->object.english+p->object.chinese;
if ('X'==ch)
{
if (number==p->number)
{
isHave=true;
printf("\n学号:%d 姓名:%s 性别:%s\n",p->number,p->name,p->sex=='B'?"男":"女");
printf("数学:%.1f 英语%.1f 语文%.1f\n",p->object.math,p->object.english,p->object.chinese);
printf("总分:%.1f 平均分:%.1f\n\n",sum,sum/3);
}
}
else if ('N'==ch)
{
if (strcmp(name,p->name)==0)
{
printf("\n学号:%d 姓名:%s 性别:%s\n",p->number,p->name,p->sex=='B'?"男":"女");
printf("数学:%.1f 英语%.1f 语文%.1f\n",p->object.math,p->object.english,p->object.chinese);
printf("总分:%.1f 平均分:%.1f\n\n",sum,sum/3);
}
isHave=true;
}
else if ('S'==ch)
{
if (sex==p->sex)
{
printf("\n学号:%d 姓名:%s 性别:%s\n",p->number,p->name,p->sex=='B'?"男":"女");
printf("数学:%.1f 英语%.1f 语文%.1f\n",p->object.math,p->object.english,p->object.chinese);
printf("总分:%.1f 平均分:%.1f\n\n",sum,sum/3);
}
isHave=true;
}
}
return isHave;
}
bool Insert(PSTU pHead,int pos) //之前的位置插入
{
int number;
char name[40];
char sex;
float grade;
int index=0;
PSTU p=pHead,pNew=NULL;
printf("您要在第几个学生前面插入:");
scanf("%d",&pos);
for (index=0;index<pos-1;index++)
{
p=p->pNext;
}
if (NULL==p||pos<1)
{
return false;
}
pNew=(PSTU)malloc(sizeof(STU));
printf("请输入插入学生的学号:",index+1);
scanf("%d",&number);
pNew->number=number;
printf("请输入插入学生的姓名:",index+1);
scanf("%s",name);
while(getchar()!='\n')
continue;
strcpy(pNew->name,name);
INPUT_ERROR_D:
printf("请输入插入学生的性别 男(B)女(G)",index+1);
scanf("%c",&sex);
sex=toupper(sex);
if (sex!='B'&&sex!='G')
{
printf("输入错误,请重新输入\n");
goto INPUT_ERROR_D;
}
pNew->sex=sex;
printf("请输入插入学生的数学成绩:");
scanf("%f",&grade);
pNew->object.math=grade;
printf("请输入插入学生的英语成绩:");
scanf("%f",&grade);
pNew->object.english=grade;
printf("请输入插入学生的语文成绩:");
scanf("%f",&grade);
pNew->object.chinese=grade;
while(getchar()!='\n')
continue;
pNew->pNext=p->pNext;
p->pNext=pNew;
return true;
}
bool Delete(PSTU pHead,int pos) //删除数据
{
PSTU p=pHead;
PSTU pSave=NULL;
int index=0;
pSave=(PSTU)malloc(sizeof(STU));
printf("您要删除第几个学生的数据:");
scanf("%d",&pos);
while(getchar()!='\n')
continue;
for (index=0;index<pos-1;index++)
{
p=p->pNext;
}
if (NULL==p||pos<1||NULL==pSave)
{
return false;
}
pSave=p->pNext;
p->pNext=pSave->pNext;
free(pSave);
return true;
}
int GetLength(PSTU p) //利用递归 求出 长度
{
if (p!=NULL)
{
return 1+GetLength(p->pNext);
}
return 0;
}
#include <string.h>
#include <stdlib.h>
//设置个全局变量 用于在不同选择不同层次时显示不同的菜单
//定义一个 OBJ结构体 用于表示学生科目成绩
typedef struct OBJ
{
float math;
float english;
float chinese;
}OBJ,* POBJ;
//定义一个 STU结构体 用于表示学生的信息
typedef struct STUDENT
{
int number; //学号
char name[40]; //姓名
char sex; //性别
OBJ object; //科目
struct STUDENT* pNext; //指向下一个
}STU,* PSTU;
PSTU Create(); //创建学生的数据
FILE* OpenFile(char Get_Choose,char* filename); //新建 打开 文件的函数
PSTU LoadFile(FILE* file,PSTU pHead); //读取文件
void SaveFile(FILE* file,PSTU pHead); //保存文件 第一个参数为要保存到哪个文件 第二个为要保存的数据
void View(PSTU pHead); //浏览学生信息
void Sort(PSTU pHead); //排序
void CopyData(PSTU p1,const PSTU p2); //复制数据 将P2的值复制进P1中 不过指向的pNext不变
bool Find(PSTU pHead); //查找学生信息
bool Insert(PSTU pHead,int pos); //插入学生信息 第一个参数是要插入的头节点所指向的链表结构 第二个是要插入的位置
bool Delete(PSTU pHead,int pos); //删除学生信息 从第几个位置开始删除pos个位置的学生信息
int GetLength(PSTU); //得到链表长度
//PSTU CleanUpList(PSTU pHead); //清空链表中的数据
/*
各函数 调用测试.........................
*/
int main()
{
FILE* file=NULL;
PSTU pHead=NULL;
char filename[40]="123";
/*各函数 调用测试 均正常 就看 LoadFile那*/
file=OpenFile('n',filename);
pHead=Create();
View(pHead);
Sort(pHead);
View(pHead);
Delete(pHead,0);
View(pHead);
Find(pHead);
Insert(pHead,0);
View(pHead);
SaveFile(file,pHead);
fclose(file);
printf("continue 任意键\n");
getchar();
file=OpenFile('o',filename);
if (NULL==file)
{
fprintf(stderr,"文件打开失败");
exit(1);
}
rewind(file);
pHead=LoadFile(file,pHead); //////////////////就是在这出了问题
if(!pHead)
printf("载入 文件失败!\n");
View(pHead);
if (file!=NULL)
{
fclose(file);
}
return 0;
}
/*
函数调用测试
*/
FILE* OpenFile(char Get_Choose,char* filename)
{
FILE* file=NULL;
Get_Choose=toupper(Get_Choose);
strcat(filename,".dat"); //加入后缀名.dat
char mode[4];
if ('N'==Get_Choose)
{
strcpy(mode,"wb+");
}
else if ('O'==Get_Choose)
{
strcpy(mode,"rb+");
}
else
{
return NULL;
}
file = fopen(filename,mode);
return file;
}
PSTU Create()
{
PSTU pHead=NULL;
PSTU p=NULL,pNew=NULL;
int n=0; //要创建的个数
int number; //学号
float grade=0.0f; //保存成绩
char name[40]; //姓名
char sex; //性别
pHead=(PSTU)malloc(sizeof(STU)); //创建头结点
pHead->pNext=NULL;
p=pHead;
printf("请输入您要创建的学生信息个数:");
scanf("%d",&n);
for (int index=0;index<n;index++)
{
pNew=(PSTU)malloc(sizeof(STU));
printf("请输入第%d个学生学号:",index+1);
scanf("%d",&number);
pNew->number=number;
printf("请输入第%d个学生姓名:",index+1);
scanf("%s",name);
while(getchar()!='\n')
continue;
strcpy(pNew->name,name);
INPUT_ERROR_B:
printf("请输入第%d个学生性别 男(B)女(G)",index+1);
scanf("%c",&sex);
sex=toupper(sex);
if (sex!='B'&&sex!='G')
{
printf("输入错误,请重新输入\n");
goto INPUT_ERROR_B;
}
pNew->sex=sex;
printf("请输入第%d个学生的数学成绩:",index+1);
scanf("%f",&grade);
pNew->object.math=grade;
printf("请输入第%d个学生的英语成绩:",index+1);
scanf("%f",&grade);
pNew->object.english=grade;
printf("请输入第%d个学生的语文成绩:",index+1);
scanf("%f",&grade);
while(getchar()!='\n')
continue;
pNew->object.chinese=grade;
p->pNext=pNew;
p=p->pNext;
pNew->pNext=NULL;
}
return pHead;
}
PSTU LoadFile(FILE* file,PSTU pHead) //主要是这个函数的问题
{
PSTU p=NULL;
PSTU pSave=NULL;
int index=0;
int length=0;
fread(&length,sizeof(int),1,file); //这里读取后 为什么为0?
if (NULL==file||0==length)
{
return NULL;
}
if (NULL!=pHead)
{
for (p=pHead,index=0;p!=NULL;p=pSave)
{
pSave=p->pNext;
free(p);
}
}
pHead=(PSTU)malloc(sizeof(STU));
p=pHead;
p->pNext=NULL;
PSTU pNew=(PSTU)malloc(sizeof(STU));
pNew->pNext=NULL;
index=0;
while(fread(pNew,sizeof(STU),1,file),pNew!=NULL&&length<3)
{
index++;
p->pNext=pNew;
pNew=(PSTU)malloc(sizeof(STU));
p=pNew;
}
return pHead;
}
void SaveFile(FILE* file,PSTU pHead)
{
PSTU p;
int length=0;
if (file!=NULL)
{
length=GetLength(pHead->pNext);
fwrite(&length,sizeof(int),1,file);
for (p=pHead->pNext;p!=NULL;p=p->pNext)
{
fwrite(p,sizeof(STU),1,file);
}
fflush(file);
}
return;
}
void View(PSTU pHead)
{
float sum;
if (NULL==pHead->pNext)
{
printf("数据为空,无法浏览\n");
return;
}
PSTU p=pHead->pNext;
while(p!=NULL)
{
sum=p->object.math+p->object.english+p->object.chinese;
printf("\n学号:%d 姓名:%s 性别:%s\n",p->number,p->name,p->sex=='B'?"男":"女");
printf("数学:%.1f 英语%.1f 语文%.1f\n",p->object.math,p->object.english,p->object.chinese);
printf("总分:%.1f 平均分:%.1f\n\n",sum,sum/3);
p=p->pNext;
}
return;
}
void Sort(PSTU pHead)
{
char ch;
PSTU p;
PSTU q;
PSTU y=(PSTU)malloc(sizeof(STU));
float p_sum,q_sum;
INPUT_ERROR_C:
printf("请问您要按 总成绩(P) 学号(X):");
ch=getchar();
while(getchar()!='\n')
continue;
ch=toupper(ch);
if (ch!='X'&&ch!='P')
{
printf("输入错误,请重新输入\n");
goto INPUT_ERROR_C;
}
if ('X'==ch)
{
for (p=pHead->pNext;p!=NULL;p=p->pNext)
{
for (q=p->pNext;q!=NULL;q=q->pNext)
{
if((p->number)>(q->number))
{
CopyData(y,p);
CopyData(p,q);
CopyData(q,y);
}
}
}
}
else
{
for (p=pHead->pNext;p!=NULL;p=p->pNext)
{
for (q=p->pNext;q!=NULL;q=q->pNext)
{
p_sum=p->object.math+p->object.english+p->object.chinese;
q_sum=q->object.math+q->object.english+q->object.chinese;
if(p_sum<=q_sum)
{
CopyData(y,p);
CopyData(p,q);
CopyData(q,y);
}
}
}
}
return;
}
void CopyData(PSTU p1,const PSTU p2) //复制数据 pNext不变
{
PSTU pNext;
pNext=p1->pNext;
*p1=*p2;
p1->pNext=pNext;
return;
}
bool Find(PSTU pHead) //查找
{
bool isHave=false;
PSTU p=pHead;
char ch;
char name[40];
int number;
char sex;
float sum;
INPUT_ERROR_D:
printf("查找方式\n学号(X) 姓名(N) 性别(S)\n");
ch=getchar();
while(getchar()!='\n')
continue;
ch=toupper(ch);
if ('X'==ch)
{
printf("学号:");
scanf("%d",&number);
}
else if ('N'==ch)
{
printf("姓名:");
scanf("%s",name);
}
else if ('S'==ch)
{
printf("性别 男(B) 女(G):");
sex=getchar();
sex=toupper(sex);
}
else
{
printf("输如错误,请重新输入\n");
goto INPUT_ERROR_D;
}
while(getchar()!='\n')
continue;
for (p=pHead->pNext;p!=NULL;p=p->pNext)
{
sum=p->object.math+p->object.english+p->object.chinese;
if ('X'==ch)
{
if (number==p->number)
{
isHave=true;
printf("\n学号:%d 姓名:%s 性别:%s\n",p->number,p->name,p->sex=='B'?"男":"女");
printf("数学:%.1f 英语%.1f 语文%.1f\n",p->object.math,p->object.english,p->object.chinese);
printf("总分:%.1f 平均分:%.1f\n\n",sum,sum/3);
}
}
else if ('N'==ch)
{
if (strcmp(name,p->name)==0)
{
printf("\n学号:%d 姓名:%s 性别:%s\n",p->number,p->name,p->sex=='B'?"男":"女");
printf("数学:%.1f 英语%.1f 语文%.1f\n",p->object.math,p->object.english,p->object.chinese);
printf("总分:%.1f 平均分:%.1f\n\n",sum,sum/3);
}
isHave=true;
}
else if ('S'==ch)
{
if (sex==p->sex)
{
printf("\n学号:%d 姓名:%s 性别:%s\n",p->number,p->name,p->sex=='B'?"男":"女");
printf("数学:%.1f 英语%.1f 语文%.1f\n",p->object.math,p->object.english,p->object.chinese);
printf("总分:%.1f 平均分:%.1f\n\n",sum,sum/3);
}
isHave=true;
}
}
return isHave;
}
bool Insert(PSTU pHead,int pos) //之前的位置插入
{
int number;
char name[40];
char sex;
float grade;
int index=0;
PSTU p=pHead,pNew=NULL;
printf("您要在第几个学生前面插入:");
scanf("%d",&pos);
for (index=0;index<pos-1;index++)
{
p=p->pNext;
}
if (NULL==p||pos<1)
{
return false;
}
pNew=(PSTU)malloc(sizeof(STU));
printf("请输入插入学生的学号:",index+1);
scanf("%d",&number);
pNew->number=number;
printf("请输入插入学生的姓名:",index+1);
scanf("%s",name);
while(getchar()!='\n')
continue;
strcpy(pNew->name,name);
INPUT_ERROR_D:
printf("请输入插入学生的性别 男(B)女(G)",index+1);
scanf("%c",&sex);
sex=toupper(sex);
if (sex!='B'&&sex!='G')
{
printf("输入错误,请重新输入\n");
goto INPUT_ERROR_D;
}
pNew->sex=sex;
printf("请输入插入学生的数学成绩:");
scanf("%f",&grade);
pNew->object.math=grade;
printf("请输入插入学生的英语成绩:");
scanf("%f",&grade);
pNew->object.english=grade;
printf("请输入插入学生的语文成绩:");
scanf("%f",&grade);
pNew->object.chinese=grade;
while(getchar()!='\n')
continue;
pNew->pNext=p->pNext;
p->pNext=pNew;
return true;
}
bool Delete(PSTU pHead,int pos) //删除数据
{
PSTU p=pHead;
PSTU pSave=NULL;
int index=0;
pSave=(PSTU)malloc(sizeof(STU));
printf("您要删除第几个学生的数据:");
scanf("%d",&pos);
while(getchar()!='\n')
continue;
for (index=0;index<pos-1;index++)
{
p=p->pNext;
}
if (NULL==p||pos<1||NULL==pSave)
{
return false;
}
pSave=p->pNext;
p->pNext=pSave->pNext;
free(pSave);
return true;
}
int GetLength(PSTU p) //利用递归 求出 长度
{
if (p!=NULL)
{
return 1+GetLength(p->pNext);
}
return 0;
}
[ 本帖最后由 々NARUTO 于 2013-4-20 13:18 编辑 ]