• 【C语言程序设计第四版】练习12-7


    #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;
    }
  • 相关阅读:
    这一年来,我的初三
    LGOJP4381 [IOI2008]Island
    BZOJ4484: [Jsoi2015]最小表示
    二分图染色及最大匹配(匈牙利算法)略解
    2019牛客多校第三场 F.Planting Trees
    性能优化 | 30个Java性能优化技巧,你会吗?
    进程 | 线程 | 当Linux多线程遭遇Linux多进程
    性能面试 | 性能测试常见面试题
    性能调优 | 如何通过性能调优突破 MySQL 数据库性能瓶颈?
    性能分析 | Java服务器内存过高&CPU过高问题排查
  • 原文地址:https://www.cnblogs.com/sidianok/p/15346008.html
Copyright © 2020-2023  润新知