C语言,提醒还书函数如何修改,1000积分悬?

1.需要用到的结构体已经构造
typedef struct times
{
int year;
int month;
int day;
}Date;//日期结构体

typedef struct borrowers
{
char bookname[name_len];//书名
char serial[length];//序号
char category[length];//类别
int id;//借阅者id
Date date1;//嵌套日期结构体
}borrow;//日常借阅信息结构体
borrow borrower[varynum];

2.事先声明函数
Date get_time(); //获取当前时间函数
int cal_day(Date); //计算借出时间函数

Date gettime()
{
Date date;
struct tm *local;
time_t nowtime;
nowtime=time(NULL); //获取时间
local=localtime(&nowtime); //转为当地时间
date.year = local->tm_year+1900;
date.month = local->tm_mon+1;
date.day = local->tm_mday;
return date;
}

int cal_day(Date d)//计算借出的总天数函数,参数是当天日子
{
Date nd = get_time();
if(nd.year == d.year)
{
if(nd.month == d.month) return nd.day - d.day;
else return nd.day-d.day +(nd.month - d.month)*30; //每月按30天计
}
else
{return ((nd.month-1)*30+nd.day) - ((d.month-1)*30 +d.day) + (nd.year-d.year)*365;} //每年按365天计
}

3.存在问题的函数
int query(Date date[],borrow borrower[])
{
for(int i =0;i<varynum;i++)
{int days = cal_day(date[i]);
printf("本书已被借出%d天\n",days);
if(days>30)
printf("%d同学所借的%s已超期%天\n",borrower[i].id,borrower[i].bookname,days-30);
}
return 0;
}

其在主函数内调用语句如下:
int query(borrower[].date1,borrower[]);

4.疑问:
(1).该函数的定义时,调用时参数该如何写,是否存在错误(结构体内嵌套的结构体数组怎么用作函数参数)
(2).该借阅信息结构体数组实际上要每天记录到文件里,但是如果该文件没有进行初始化,使用该函数时是否会指向野指针?并且,如何用写语句,使该函数调用该文件里的结构体数组数据。

(1).该函数的定义时,调用时参数该如何写,是否存在错误(结构体内嵌套的结构体数组怎么用作函数参数)
---------------------------------------------------
这个估计你是写晕头了,你是要这个效果吧:
int query(borrow borrower[])
{
for(int i =0;i<varynum;i++)
{int days = cal_day(borrower[i].date1);
printf("本书已被借出%d天\n",days);
if(days>30)
printf("%d同学所借的%s已超期%天\n",borrower[i].id,borrower[i].bookname,days-30);
}
return 0;
}
------------------------------------
(2).该借阅信息结构体数组实际上要每天记录到文件里,但是如果该文件没有进行初始化,使用该函数时是否会指向野指针?并且,如何用写语句,使该函数调用该文件里的结构体数组数据。
-----------------------------------
你说的没有初始化是指什么呢?文件不存在?还是文件存在但内容是错误的?追问

单单执行这个函数时,文件还没有新建,所以这个函数实际上调用的不是文件里的数据,没有达到题目要求

追答

你贴的这段代码里并没有涉及野指针的问题,只是代码健壮性不够而已。
对于严谨的程序,当数据是外来时,都要考虑数据有效性,所以一般会在程序里初始化缺省值,如果文件不存在,可以能用缺省值或提示用户输入。即使文件存在,读出来的数据也是要校验合法性检验的,特别是字符串,非法字符串没有'\0'结束符可能会导致缓冲区溢出。
--------------------
至于读取文件问题,你需要用调用fread、fwrite函数来操作。

追问

void query(borrow borrower[])
{ FILE *fp3=fopen("borrowers.txt","a");
fseek(fp3,0,SEEK_END);
int num=ftell(fp3)/sizeof(borrow);
fread(borrower,sizeof(borrow),num,fp3);
for(int i =0;i30)
printf("%d同学所借的%s已超期%d天\n",borrower[i].id,borrower[i].bookname,days-30);
}
return 0;
}

追答

首先存储结构体数据不要用txt文本格式操作,应该用二进制操作。
FILE *fp3=fopen("borrowers.db","a+b");
然后如果你要操作多于一个borrowers数据的,你需要seek到与i对应的位置进行读写,还得建立一套内存和文件之间比较可靠的数据同步机制,简单来讲你得设计一个文件数据save和load的机制

追问

按您所说修改了一下文件格式,但是这个函数是为了把之前读入到fp3所指文件中的数据(两个)筛选出超期的,测试了一下会多输出两个0号同学所借的《》已超期737484天,不知道怎么回事?
实际输入了两个,但是fp3所指文件说有4个,哪个语句错了

追答

超期737484天这个典型就是你从文件读出来的时间有错误,应该是你的文件读写不配套,写进去的位置跟读的位置不一致导致的。

追问

方便私信吗?

追答

可以,你发文件给我吧

温馨提示:答案为网友推荐,仅供参考
第1个回答  2020-07-04
1.
int query(borrow borrower[])
{
for(int i =0;i<varynum;i++)
{int days = cal_day(borrower[i].date1);
printf("本书已被借出%d天\n",days);
if(days>30)
printf("%d同学所借的%s已超期%天\n",borrower[i].id,borrower[i].bookname,days-30);
}
return 0;
}

query(borrower);

2.数组哪来的野指针的说法,大不了就是为读取的文件为空,数组有效个数也为0就好了,操作前做好判断,确认数组是否被初始化就行了
相似回答