要么改变世界,要么适应世界

记一次C语言程序设计

2020-07-02 19:32:00
117
目录

背景

那是一个闷热的下午,正值期末复习之际,突然手机响了:

然后因为是高中同桌兼舍友,所以就立马接了下来。但是当时我这边刚好是准备考试,所以时间上肯定不充裕,原本是想着两三天写出来,但是最后发现一天左右就完成了。但是功能并没有完全实现,还差最后的功能没有做出来,也没有过多的测试。

题目

其实C语言很多课程设计题目大多是使用结构体+文件操作(不排除大神的课设做得很复杂的情况),我当年拿到的就是学生成绩管理系统,对!就是这种烂大街的题目,这类题也是使用结构体+文件操作就可以解决,但是当时年少不知事,文件操作我自己一直掌握得不好,所以当时的程序无法保存数据~~,当时我还写了好久,在界面美观(狗屁美观,现在想想就是太花里胡哨了,在黑框里谈啥美观)上。所以本次课设,我就不考虑啥美观了,毕竟时间有限,能力也有限,简单构思了几分钟后,就根据整体框架设计结构体了,然后…………

源程序

/*
 * @Author: YaleXin
 * @Date: 2020-05-26 15:12:01
 * @LastEditTime: 2020-05-27 15:09:36
 * @LastEditors: YaleXin
 * @Description:
 * @FilePath: \my_c_workspace\maoning\1.c
 * @祈祷不出现BUG
 */
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define OK 1
#define ERROR 0
typedef struct DiscInfo {
    char name[50];
    char country[50];
    char type[50];
    char director[50];
    char producer[50];
    char stars[500];
    int inventory;
    struct DiscInfo *next;
} DiscInfo;
// 每一条借阅记录
typedef struct RentInfo {
    long CId;
    char DName[50];
    long long BDate;
    long long RDate;
    long rentNum;
    int isReturn;
    struct RentInfo *next;
} RentInfo;
typedef struct Blist {
    char DName[50];
    struct Blist *next;
} Blist;
typedef struct CustomerInfo {
    long id;
    char name[50];
    long acount;
    Blist *RentList;
    struct CustomerInfo *next;
} CustomerInfo;
int customerInitial(CustomerInfo **L) {
    char buffer[50];
    long id;
    FILE *fp = fopen("customer.txt", "r");
    if (fp == NULL)
        printf("customer.txt not exist!\n");
    else {
        while (fscanf(fp, "%ld", &id) > 0) {
            CustomerInfo *cRead = (CustomerInfo *)malloc(sizeof(CustomerInfo));
            cRead->RentList = NULL;
            cRead->next = NULL;
            cRead->id = id;
            fscanf(fp, "%s", cRead->name);
            fscanf(fp, "%ld", &cRead->acount);
            fscanf(fp, "%s", buffer);
            while (strcmp(buffer, "END")) {
                Blist *b = (Blist *)malloc(sizeof(Blist));
                strcpy(b->DName, buffer);
                b->next = cRead->RentList;
                cRead->RentList = b;
                fscanf(fp, "%s", buffer);
            }
            cRead->next = (*L);
            (*L) = cRead;
        }
        fclose(fp);
        printf("\n\n\n读取到的顾客信息:\n\n");
        CustomerInfo *c = *L;
        while (c != NULL) {
            printf("%ld %s %ld", c->id, c->name, c->acount);
            Blist *b = c->RentList;
            while (b != NULL) {
                printf(" %s", b->DName);
                b = b->next;
            }
            printf("\n");
            c = c->next;
        }
    }
    system("pause");
    return OK;
}
int discInitial(DiscInfo **L) {
    char buffer[500];
    FILE *fp = fopen("disc.txt", "r");
    if (fp == NULL)
        printf("disc.txt not exist!\n");
    else {
        while (fscanf(fp, "%s", buffer) > 0) {
            DiscInfo *dRead = (DiscInfo *)malloc(sizeof(DiscInfo));
            dRead->next = NULL;
            strcpy(dRead->name, buffer);
            fscanf(fp, "%s", dRead->country);
            fscanf(fp, "%s", dRead->type);
            fscanf(fp, "%s", dRead->director);
            fscanf(fp, "%s", dRead->producer);
            fscanf(fp, "%s", dRead->stars);
            fscanf(fp, "%d", &dRead->inventory);
            dRead->next = (*L);
            *L = dRead;
        }
        fclose(fp);
        printf("\n\n\n读取到的碟片信息:\n\n");
        DiscInfo *d = *L;
        while (d != NULL) {
            printf("%s %s %s %s %s %s %d\n", d->name, d->country, d->type,
                   d->director, d->producer, d->stars, d->inventory);
            d = d->next;
        }
    }
    system("pause");
    return OK;
}
int rentInitial(RentInfo **L) {
    char buffer[50];
    long id;
    FILE *fp = fopen("rent.txt", "r");
    if (fp == NULL)
        printf("rent.txt not exist!\n");
    else {
        while (fscanf(fp, "%ld", &id) > 0) {
            RentInfo *rRead = (RentInfo *)malloc(sizeof(RentInfo));
            rRead->next = NULL;
            rRead->CId = id;
            fscanf(fp, "%s", rRead->DName);
            fscanf(fp, "%lld", &rRead->BDate);
            fscanf(fp, "%lld", &rRead->RDate);
            fscanf(fp, "%ld", &rRead->rentNum);
            fscanf(fp, "%d", &rRead->isReturn);
            rRead->next = *L;
            *L = rRead;
        }
        fclose(fp);
        printf("\n\n\n读取到的借阅信息\n\n");
        RentInfo *r = *L;
        while (r != NULL) {
            printf("%ld %s %lld %lld %ld %d\n", r->CId, r->DName, r->BDate,
                   r->RDate, r->rentNum, r->isReturn);
            r = r->next;
        }
    }
    system("pause");
    return OK;
}
int discAdd(DiscInfo **L) {
    DiscInfo *newDisc = (DiscInfo *)malloc(sizeof(DiscInfo));
    newDisc->next = NULL;
    printf("请输入影碟名字:\n");
    scanf("%s", newDisc->name);
    printf("请输入影碟国家:\n");
    scanf("%s", newDisc->country);
    printf("请输入影碟类型:\n");
    scanf("%s", newDisc->type);
    printf("请输入影碟导演:\n");
    scanf("%s", newDisc->director);
    printf("请输入影碟制片人:\n");
    scanf("%s", newDisc->producer);
    printf("请输入影碟主演明星(如有多个,每个明星之间以空格隔开):\n");
    getchar();
    fgets(newDisc->stars, sizeof(newDisc->stars), stdin);
    printf("请输入影碟库存量:\n");
    scanf("%d", &newDisc->inventory);
    if (*L == NULL) {
        *L = newDisc;
    } else {
        newDisc->next = *L;
        *L = newDisc;
    }
    printf("添加完毕\n");
    system("pause");
    return OK;
}
int discQuery(DiscInfo *L) {
    DiscInfo *p = L;
    printf("请输入您想要查询的碟片名字:\n");
    char query[50];
    scanf("%s", query);
    while (p != NULL) {
        if (!strcmp(query, p->name)) break;
        p = p->next;
    }
    if (p != NULL) {
        if (p->inventory > 0)
            printf("可以借阅!\n");
        else
            printf("不可以借阅,因为库存为零\n");
    } else
        printf("不存在该影碟");
    system("pause");
    return OK;
}
int discDelete(DiscInfo **L) {
    if ((*L) == NULL) {
        printf("还没有用户,无法删除!\n");
        system("pause");
        return ERROR;
    }
    DiscInfo *p1 = (*L)->next, *p2 = *L;
    printf("请输入您想要删除的碟片名字:\n");
    char query[50];
    scanf("%s", query);
    // 删除头节点
    if (!strcmp((*L)->name, query)) {
        (*L) = (*L)->next;
        free(p2);
        printf("删除成功");

    } else {
        while (p1 != NULL) {
            if (!strcmp(query, p1->name)) break;
            p2 = p1;
            p1 = p1->next;
        }
        if (p1 == NULL)
            printf("不存在该影片\n");
        else {
            p2->next = p1->next;
            free(p1);
            printf("删除成功");
        }
    }
    system("pause");
    return OK;
}
int discModify(DiscInfo **L) {
    DiscInfo *p = *L;
    printf("请输入您想要修改的碟片的名字:\n");
    char query[50];
    scanf("%s", query);
    while (p != NULL) {
        if (!strcmp(query, p->name)) break;
        p = p->next;
    }
    if (p != NULL) {
        printf("请输入新影碟国家:\n");
        scanf("%s", p->country);
        printf("请输入新影碟类型:\n");
        scanf("%s", p->type);
        printf("请输入新影碟导演:\n");
        scanf("%s", p->director);
        printf("请输入新影碟制片人:\n");
        scanf("%s", p->producer);
        printf("请输入新影碟主演明星(如有多个,每个明星之间以空格隔开):\n");
        getchar();
        fgets(p->stars, sizeof(p->stars), stdin);
        printf("请输入新影碟库存量:\n");
        scanf("%d", &p->inventory);
        printf("修改成功!\n");
    } else
        printf("不存在该影碟");
    system("pause");
    return OK;
}
int customerAdd(CustomerInfo **L) {
    CustomerInfo *newCustomer = (CustomerInfo *)malloc(sizeof(CustomerInfo));
    newCustomer->next = NULL;
    printf("请输入顾客名字:\n");
    scanf("%s", newCustomer->name);
    printf("请输入顾客账户id:\n");
    scanf("%ld", &newCustomer->id);
    printf("请输入顾客账户金额:\n");
    scanf("%ld", &newCustomer->acount);
    newCustomer->RentList = NULL;
    if (*L == NULL) {
        *L = newCustomer;
    } else {
        newCustomer->next = *L;
        *L = newCustomer;
    }
    printf("添加完毕\n");
    system("pause");
    return OK;
}
int customerDelete(CustomerInfo **L) {
    if ((*L) == NULL) {
        printf("还没有用户,无法删除!\n");
        system("pause");
        return ERROR;
    }
    CustomerInfo *p1 = (*L)->next, *p2 = *L;
    printf("请输入想要删除的顾客名字:\n");
    char query[50];
    scanf("%s", query);
    // 删除头节点
    if (!strcmp((*L)->name, query)) {
        if ((*L)->RentList != NULL) {
            printf("该用户还未归还借阅的碟片,不能删除用户\n");
        } else {
            (*L) = (*L)->next;
            free(p2);
            printf("删除成功");
        }
    } else {
        while (p1 != NULL) {
            if (!strcmp(query, p1->name)) break;
            p2 = p1;
            p1 = p1->next;
        }
        if (p1 == NULL)
            printf("不存在该用户\n");
        else {
            if (p1->RentList != NULL) {
                printf("该用户还未归还借阅的碟片,不能删除用户\n");
            } else {
                p2->next = p1->next;
                free(p1);
                printf("删除成功");
            }
        }
    }
    system("pause");
    return OK;
}
int customerModify(CustomerInfo **L) {
    CustomerInfo *p = *L;
    printf("请输入想要修改的顾客的账户id:\n");
    long query;
    scanf("%ld", &query);
    while (p != NULL) {
        if (query != p->id) break;
        p = p->next;
    }
    if (p != NULL) {
        printf("请输入新顾客名字:\n");
        scanf("%s", p->name);
        printf("请输入新顾客账户金额:\n");
        scanf("%ld", &p->acount);
        printf("修改成功!\n");
    } else
        printf("不存在该用户");
    system("pause");
    return OK;
}
int borrowDisc(RentInfo **RL, DiscInfo **DL, CustomerInfo **CL) {
    DiscInfo *dp = *DL;
    CustomerInfo *cp = *CL;
    int id;
    while (1) {
        printf("请输入借阅人的id,输入“0”结束本次借阅\n");
        scanf("%ld", &id);
        if (!id) break;
        while (cp != NULL) {
            if (cp->id == id) break;
            cp = cp->next;
        }
        if (cp == NULL) {
            printf("用户不存在,请重新输入\n");
            continue;
        } else if (cp->acount < 20) {
            printf("租金不足20元,无法借阅\n");
        } else {
            printf("请输入借阅日期(格式:年月日时分秒,如20200526192222)\n");
            long long date;
            // scanf("%lld", &date);
            while (scanf("%lld", &date) &&
                   !(date < 99999999999999 && date > 10000000000000)) {
                printf("日期格式错误\n");
                //  continue;
            }
            printf(
                "请输入借阅的碟片数量(一次只能借阅同种碟片的一片,但是可以借阅"
                "不同的碟片)\n");
            int count = 0;
            scanf("%d", &count);
            int status[100];
            char buffer[50];
            for (int i = 1; i <= count; i++) {
                printf("请输入第%d个碟片的名字\n", i);
                scanf("%s", buffer);
                dp = *DL;
                while (dp != NULL) {
                    if (!strcmp(buffer, dp->name)) break;
                    dp = dp->next;
                }
                if (dp == NULL || dp->inventory == 0)
                    status[i] = 0;
                else {
                    dp->inventory--;
                    RentInfo *newRent = (RentInfo *)malloc(sizeof(RentInfo));
                    newRent->next = NULL;
                    newRent->BDate = date;
                    newRent->CId = cp->id;
                    newRent->isReturn = 0;
                    strcpy(newRent->DName, buffer);
                    if (*RL == NULL) {
                        *RL = newRent;
                    } else {
                        newRent->next = *RL;
                        *RL = newRent;
                    }
                    newRent->isReturn = 0;
                    Blist *newBlist = (Blist *)malloc(sizeof(Blist));
                    newBlist->next = NULL;
                    strcpy(newBlist->DName, buffer);
                    if (cp->RentList == NULL) {
                        cp->RentList = newBlist;
                    } else {
                        newBlist->next = cp->RentList;
                        cp->RentList = newBlist;
                    }
                    status[i] == 1;
                }
            }
            int successCount = 0;
            for (int i = 1; i <= count; i++)
                if (!status[i])
                    printf("借阅的第%d个碟片失败\n");
                else
                    successCount++;
            printf("本次借阅碟片成功数量:%d,失败数量:%d\n", successCount,
                   count - successCount);
        }
    }
    printf("操作成功\n");
    system("pause");
    return OK;
}  // 2020 0222 181212
int getDays(long long num1, long long num2) {
    int months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int sum = 0, year, month, day;
    year = (num1 - num2) / 10000000000;
    month = (num1 - num2) / 100000000;
    day = (num1 - num2) / 1000000;
    for (int i = 0; i <= month - 2; i++) sum += months[i];
    sum += day;
    sum += year * 365;
    return sum;
}
int returnDisc(RentInfo **RL, DiscInfo **DL, CustomerInfo **CL) {
    DiscInfo *dp = *DL;
    CustomerInfo *cp = *CL;
    int id;
    while (1) {
        printf("请输入归还人的id,输入“0”结束本次归还\n");
        scanf("%ld", &id);
        if (!id) break;
        while (cp != NULL) {
            if (cp->id == id) break;
            cp = cp->next;
        }
        if (cp == NULL) {
            printf("用户不存在,请重新输入\n");
            continue;
        } else {
            printf("请输入归还日期(格式:年月日时分秒,如20200526192222)\n");
            long long date;
            // scanf("%lld", &date);
            while (scanf("%lld", &date) &&
                   !(date < 99999999999999 && date > 10000000000000)) {
                printf("日期格式错误\n");
                //  continue;
            }
            printf("请输入归还的碟片数量\n");
            int count = 0;
            scanf("%d", &count);
            int status[100];
            char buffer[100][50];
            RentInfo *rp;
            int totalCost = 0, reality = 0;
            for (int i = 1; i <= count; i++) {
                printf("请输入第%d个碟片的名字\n", i);
                scanf("%s", buffer[i]);
                rp = *RL;
                while (rp != NULL) {
                    if (!strcmp(rp->DName, buffer[i]) && !(rp->isReturn)) {
                        rp->RDate = date;
                        int days = getDays(rp->RDate, rp->BDate);
                        // 日期错误
                        if (days <= 0)
                            status[i] = 0;
                        else {
                            rp->rentNum = days / 3;
                            if (days % 3 > 0) rp->rentNum++;
                            totalCost += rp->rentNum;
                            // 不够钱
                            if (cp->acount + 20 - rp->rentNum < 0)
                                status[i] = 0;
                            else {
                                reality += rp->rentNum;
                                cp->acount = cp->acount + 20 - rp->rentNum;
                                status[i] = 1;
                                // 记上已经归还
                                rp->isReturn = 1;
                                DiscInfo *d = *DL;
                                while (d != NULL)
                                    if (!strcmp(d->name, buffer[i])) break;
                                //库存加一
                                d->inventory++;
                                Blist *b1 = cp->RentList->next,
                                      *b2 = cp->RentList;
                                // 头节点
                                if (!strcmp(cp->RentList->DName, buffer[i])) {
                                    cp->RentList = NULL;

                                } else {
                                    while (b1 != NULL)
                                        if (!strcmp(b1->DName, buffer[i]))
                                            break;
                                        else {
                                            b2 = b1;
                                            b1 = b1->next;
                                        }
                                    // 头节点
                                    if (b1 == NULL)
                                        b2 = b2->next;
                                    else
                                        b2->next = b1->next;
                                }
                            }
                        }
                        break;
                    }
                    rp = rp->next;
                }
                if (rp == NULL || !(rp->isReturn)) {
                    status[i] = 0;
                }
            }

            int successCount = 0;
            for (int i = 1; i <= count; i++)
                if (!status[i])
                    printf("归还第%d个碟片失败\n", i);
                else
                    successCount++;
            printf("本次归还碟片成功数量:%d,失败数量:%d\n", successCount,
                   count - successCount);
            printf("本次归还碟片需要支付总费用%d,实际支付:%d\n", totalCost,
                   reality);
        }
    }
    printf("操作成功\n");

    system("pause");
    return OK;
}
int save(RentInfo *RL, DiscInfo *DL, CustomerInfo *CL) {
    FILE *fp = fopen(".\\rent.txt", "w+");
    if (fp != NULL) {
        while (RL != NULL) {
            fprintf(fp, "%ld ", RL->CId);
            fprintf(fp, "%s ", RL->DName);
            fprintf(fp, "%lld ", RL->BDate);
            fprintf(fp, "%lld ", RL->RDate);
            fprintf(fp, "%ld ", RL->rentNum);
            fprintf(fp, "%d ", RL->isReturn);
            fputc('\n', fp);
            RL = RL->next;
        }
        printf("rent.txt保存成功\n");
        fclose(fp);
    } else {
        printf("rent.txt保存失败\n");
    }
    fp = fopen(".\\customer.txt", "w+");
    if (fp != NULL) {
        while (CL != NULL) {
            fprintf(fp, "%ld ", CL->id);
            fprintf(fp, "%s ", CL->name);
            fprintf(fp, "%ld ", CL->acount);
            Blist *b = CL->RentList;
            while (b != NULL) {
                fprintf(fp, "%s ", b->DName);
                b = b->next;
            }
            char end[] = {'E', 'N', 'D', '\n'};
            fprintf(fp, "%s", "END\n");
            CL = CL->next;
        }
        printf("customer.txt保存成功\n");
        fclose(fp);
    } else {
        printf("customer.txt保存失败\n");
    }
    fp = fopen(".\\disc.txt", "w+");
    if (fp != NULL) {
        while (DL != NULL) {
            fprintf(fp, "%s ", DL->name);
            fprintf(fp, "%s ", DL->country);
            fprintf(fp, "%s ", DL->type);
            fprintf(fp, "%s ", DL->director);
            fprintf(fp, "%s ", DL->producer);
            fprintf(fp, "%s ", DL->stars);
            fprintf(fp, "%d ", DL->inventory);
            fputc('\n', fp);
            DL = DL->next;
        }
        printf("customer.txt保存成功\n");
        fclose(fp);
    } else {
        printf("customer.txt保存失败\n");
    }
    system("pause");
    return OK;
}
int main() {
    CustomerInfo *CL = NULL;
    DiscInfo *DL = NULL;
    RentInfo *RL = NULL;
    customerInitial(&CL);
    discInitial(&DL);
    rentInitial(&RL);
    int exit = 0;
    while (!exit) {
        int choose;
        system("cls");
        printf("1.影碟添加\n\n");
        printf("2.影碟删除\n\n");
        printf("3.影碟修改\n\n");
        printf("4.顾客添加\n\n");
        printf("5.顾客删除\n\n");
        printf("6.顾客修改\n\n");
        printf("7.碟片查询\n\n");
        printf("8.碟片借阅\n\n");
        printf("9.碟片归还\n\n");
        printf("0.退出\n\n");
        scanf("%d", &choose);
        switch (choose) {
            case 1:
                discAdd(&DL);
                break;
            case 2:
                discDelete(&DL);
                break;
            case 3:
                discModify(&DL);
                break;
            case 4:
                customerAdd(&CL);
                break;
            case 5:
                customerDelete(&CL);
                break;
            case 6:
                customerModify(&CL);
                break;
            case 7:
                discQuery(DL);
                break;
            case 8:
                borrowDisc(&RL, &DL, &CL);
                break;
            case 9:
                returnDisc(&RL, &DL, &CL);
                break;
            case 0:
                save(RL, DL, CL);
                system("cls");
                printf("正在退出...");
                Sleep(1000);
                system("cls");
                exit = 1;
        }
    }
    return 0;
}

反思

  • 写完后才发现time.h库文件中就有*time_t类型的变量,十分方便记录时间。而不是像我一样,直接拿long long变量来表示~~~。

  • 客户的结构体设计得不合理,应该把借阅队列设置为影碟类型,而不是简单地用字符串简单表示。

  • …………

历史评论
开始评论