#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
typedef struct book{
char name[10]={0};
char id[8]={0}; //存八位编号
int loaned; //借出
int num; //总数
double price;
char publisher[10]={0};
char author[5]={0};
struct book*next;
}book;
typedef struct student{
char id[8]={0};
char name[10]={0};
int overdue; //逾期数
char borrow[5][8]={0}; //借书数,最大为5,用编号存
struct student*next;
}student;
student* Is_student_id(char *id){
student sd,*p=NULL;
FILE*fp=NULL;
fp=fopen("student.dat","rb");
if(fp==NULL){
printf("打开文件失败!");
exit(1);
}
int flag=0;
fseek(fp,0,SEEK_SET);
while(!feof(fp)){
fwrite(&sd,sizeof(student),1,fp);
if(strcmp(sd.id,id)==0){
p=&sd;
flag=1;
}
}
return p;
}
int main(){
// student sd = {"123456","asd",1,"格林"};
// FILE*fp=NULL;
// fp=fopen("student.dat","w");
// fwrite(&sd,sizeof(student),1,fp);
if(Is_student_id("123456")){
printf("asd");
}else printf("qwe");
return 0;
}
在Is_student_id函数中,存在几个问题:
fwrite函数是写入操作,应该用于将数据写入到文件中,而不是从文件中读取数据。应该使用fread函数来从文件中读取数据。
在while循环中,没有判断fread函数的返回值,也没有判断读取的数据是否为最后一个数据。因此,可能会出现读取多余的数据的情况,导致指针越界或者陷入死循环。
在while循环中,每次读取一个student结构体,但是没有将它添加到链表中,也没有判断当前student结构体是否是需要查找的结构体。因此,即使读取到了正确的数据,也无法正确返回对应的指针。
为了解决这些问题,你可以修改Is_student_id函数的实现:
student* Is_student_id(char *id) {
student *p = NULL, *head = NULL;
FILE *fp = NULL;
fp = fopen("student.dat", "rb");
if (fp == NULL) {
printf("打开文件失败!");
exit(1);
}
head = (student*)malloc(sizeof(student));
while (fread(head, sizeof(student), 1, fp)) {
if (strcmp(head->id, id) == 0) {
p = head;
break;
}
head->next = (student*)malloc(sizeof(student));
head = head->next;
}
head->next = NULL;
fclose(fp);
return p;
}
这里使用了一个链表来保存读取到的student结构体,同时在读取每个结构体时,判断它是否是需要查找的结构体,如果是,则将对应的指针返回。如果读取到了最后一个结构体,就将链表的末尾指针设为NULL,并关闭文件,最后返回指针。