#include <string.h>
#include <stdlib.h>
#include <stdio.h>
long size;
struct LogData{
long logid;
char logdate[11];
char lognote[15];
double charge;
double balance;
};
int inputchoise(void){
int mychoise;
printf("
Enter your choice:
");
printf("1-Add a new cash LOG.
2-List All Cash LOG.
");
printf("3-Query Last Cash LOG.
4-Update cash LOG.
0-End program.
");
scanf("%d", &mychoise);
return mychoise;
}
long getLogcount(FILE *cfptr){
long begin,end,logcount;
fseek(cfptr, 0L, SEEK_SET);
begin = ftell(cfptr);
fseek(cfptr, 0L, SEEK_END);
end = ftell(cfptr);
logcount = (end-begin)/size;
// printf("logcount = %ld
",logcount);
return logcount;
}
void UpdateLog(FILE *cfptr){
struct LogData c_log,o_log,f_log;
long logcount;
int id, w_flag;
w_flag=0;
logcount = getLogcount(cfptr);
if (logcount != 0) {
printf("Enter the update id:
");
scanf("%d", &id);
if (id > logcount) {
printf("Input id is error!
");
return;
}else{
if (id == 1) {
o_log.logid = id;
printf("Input logdate(format: 2006-01-01):");
scanf("%s", o_log.logdate);
printf("Input lognote:");scanf("%s", o_log.lognote);
printf("Input Charge: Income+and expend-:");
scanf("%lf", &o_log.charge);
o_log.balance = o_log.charge;
fseek(cfptr, 0L, SEEK_SET); //到文件头部文件指针
fwrite(&o_log, size, 1, cfptr);
while (!feof(cfptr)) {
if (w_flag) {
fseek(cfptr, -size, SEEK_CUR);
c_log.balance = o_log.balance + c_log.charge;
o_log = c_log;
fwrite(&o_log, size, 1, cfptr);
}
fread(&c_log, size, 1, cfptr);
w_flag = 1;
}
}else{
fseek(cfptr, size*(id-2), SEEK_SET); //把上一个的余额算出来
fread(&f_log, size, 1, cfptr);
o_log.logid = id;
printf("Input logdate(format: 2006-01-01):");
scanf("%s", o_log.logdate);
printf("Input lognote:");scanf("%s", o_log.lognote);
printf("Input Charge: Income+and expend-:");
scanf("%lf", &o_log.charge);
o_log.balance = f_log.balance + o_log.charge;
// printf("ftell = %ld
", ftell(cfptr));
// 这里有一个问题,理论前面的了文件,这里写入刚好,打印出来文件指针的位置也是对的,但写入就不对,本来不需要这个
// 我的个人理解是读写缓存取的原理不一样,前面是读的缓存区,直接写入的话,不合适,需要对文件指针进行一步操作。
// 也就是在读写切换的时候,需要对文件指针的位置进行确认操作。
// fseek(cfptr, size*(id-1), SEEK_SET);
ftell(cfptr);
fwrite(&o_log, size, 1, cfptr);
// printf("_blksize %d",cfptr->_blksize);
// printf("_lbfsize %d",cfptr->_lbfsize);
while (!feof(cfptr)) {
if (w_flag) {
fseek(cfptr, -size, SEEK_CUR);
c_log.balance = o_log.balance + c_log.charge;
o_log = c_log;
fwrite(&o_log, size, 1, cfptr);
}
fread(&c_log, size, 1, cfptr);
w_flag = 1;
}
}
}
}else
printf("no log in file!
");
}
void ListAllLog(FILE *cfptr){
struct LogData log;
fseek(cfptr, 0L, SEEK_SET);
fread(&log, size, 1, cfptr);
printf("logid logdate lognote charge balance
");
while (!feof(cfptr)) {
printf("%6ld %-11s %-15s %10.2lf %10.2lf
",
log.logid, log.logdate, log.lognote, log.charge, log.balance);
fread(&log, size, 1, cfptr);
}
}
void QueryLastLog(FILE *cfptr){
struct LogData log;
long logcount;
logcount = getLogcount(cfptr);
if (logcount>0) {
fseek(cfptr, size*(logcount-1), SEEK_SET);
fread(&log, size, 1, cfptr);
printf("The last log is:
");
printf("logid:%-6ld
logdata:%-11s
lognote:%-15s
",
log.logid, log.logdate,log.lognote);
printf("charge:%-10.2lf
balance:%-10.2f
",
log.charge, log.balance);
}else
printf("no log in file!
");
}
void AddNewLog(FILE *cfptr){
struct LogData log, lastlog;
long logcount;
// logcount=getLogcount(cfptr);
printf("Input logdate(format: 2006-01-01):");
scanf("%s", log.logdate);
printf("Input lognote:");scanf("%s", log.lognote);
printf("Input Charge: Income+and expend-:");
scanf("%lf", &log.charge);
logcount=getLogcount(cfptr);
// printf("AddNewLog_logcount=%ld
", logcount);
if (logcount>0) {
fseek(cfptr, size*(logcount-1), SEEK_SET);
fread(&lastlog, size, 1, cfptr);
log.logid = lastlog.logid + 1;
log.balance = log.charge + lastlog.balance;
}else{
log.logid =1;
log.balance = log.charge;
}
fwrite(&log, sizeof(struct LogData), 1, cfptr);
rewind(cfptr);
printf("logid=%ld
", log.logid);
}
int main(void){
FILE *fp; int choice;
if ((fp=fopen("cashbox.dat", "r+"))==NULL) {
printf("can not open file cashbox.dat!
");
exit(0);
}
size = sizeof(struct LogData);
while ((choice = inputchoise()) != 0) {
switch (choice) {
case 1:
AddNewLog(fp);
break;
case 2:
ListAllLog(fp);
break;
case 3:
QueryLastLog(fp);break;
case 4:
UpdateLog(fp);break;
default:
printf("Input Error.");
break;
}
}
if (fclose(fp)) {
printf("Can not close the file!
");
exit(0);
}
return 0;
}