标题:这代码写完,我差不多就已经不认识了。
只看楼主
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
结帖率:95.65%
已结贴  问题点数:20 回复次数:22 
这代码写完,我差不多就已经不认识了。
题目:写一个图书管理程序,要求可以增加记录,读取记录,删除记录,修改记录。

我从11点半写到1点半,然后越写越觉得这代码写的可真蠢。

程序代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
                 char title[50];
                 char author[50];
                 float value;
                 int del_tag;
               }BOOKS;
void menu(void);
void f_read(void);
void data_add(void);
void data_delete(void);
FILE * f_open(void);
void f_write(BOOKS a[], int arrays);
long int datas = 0;

int main(void)
{
    typedef void(*P_FUN)(void);
    P_FUN fun_M[3] = { f_read,data_delete,data_add };
    int option = 0;
    FILE *p_file;

    p_file = f_open();
    fclose(p_file);

    while (menu(), scanf("%d", &option) == 1)
    {
        if (option >= 3)
            printf("该选项不存在\n");
        else if (option < 0)
            printf("该选项不存在\n");
        else if (!datas && option != 2)
            printf("文件中没有记录。\n");
        else
            fun_M[option]();
    }
    return 0;
}

void menu(void)
{
    printf("0) 读取文件\n");
    printf("1) 删除/修改记录\n");
    printf("2) 增加记录\n");
    printf("q) 退出\n");
}

void f_read(void)
{
    FILE * p_file;
    long int data_in = 0;
    int st_size = sizeof(BOOKS);
    BOOKS book;

    p_file = f_open();
    for (data_in = 0; data_in < datas; data_in += st_size)
    {
        fseek(p_file, data_in, SEEK_SET);
        fread(&book, sizeof(BOOKS), 1, p_file);
        printf("%-25s %s  ¥%.2f\n", book.title, book.author, book.value);
    }

    fseek(p_file, 0, SEEK_END);
    datas = ftell(p_file);
    fclose(p_file);
}

void data_add(void)
{
    BOOKS a;
    FILE * p_file;
    p_file = f_open();

    while (getchar() != '\n');
    while (printf("输入书名(空行结束):"), gets(a.title) != NULL && a.title[0] != '\0')
    {
        while (printf("输入作者:"), gets(a.author) == NULL || a.author[0] == '\0');
        printf("输入单价:");
        scanf("%f", &a.value);
        a.del_tag = 1;
        while (getchar() != '\n');
        fwrite(&a, sizeof(BOOKS), 1, p_file);
    }
    fseek(p_file, 0, SEEK_END);
    datas = ftell(p_file);
    fclose(p_file);
}

void data_delete(void)
{
    int arrays = datas / sizeof(BOOKS);
    BOOKS a[arrays];
    int n, array_in;
    FILE * p_file;

    p_file = f_open();

    for (n = 0, array_in = 0; n < datas && array_in < arrays; array_in++, n += sizeof(BOOKS))
    {
        fseek(p_file, n, SEEK_SET);
        fread(&a[array_in], sizeof(BOOKS), 1, p_file);
    }
    fclose(p_file);

    while (printf("0.删除\n1.修改\n2.返回主菜单\n"), scanf("%d", &n) == 1 && n != 2)
    {
        if (!n)
        {
            for (array_in = 0; array_in < arrays; array_in++)
                printf("%d %s %s: %.2f\n", array_in, a[array_in].title, a[array_in].author, a[array_in].value);
            while (printf("输入要删除的记录的编号,可选范围0-%d(q退出):", arrays - 1), scanf("%d", &array_in) == 1)
            {

                if (array_in > arrays)
                    printf("记录不存在.\n");
                else if (!a[array_in].del_tag)
                    printf("记录不存在.\n");
                else
                    a[array_in].del_tag = 0;
            }
            while (getchar() != '\n');
        }
        else if (n == 1)
        {
            for (array_in = 0; array_in < arrays; array_in++)
                printf("%d %s %s: %.2f\n", array_in, a[array_in].title, a[array_in].author, a[array_in].value);
            while (printf("输入要修改的记录的编号,可选范围0-%d(q退出):", arrays - 1), scanf("%d", &array_in) == 1)
            {

                if (array_in > arrays)
                    printf("记录不存在\n");
                else if (!a[array_in].del_tag)
                    printf("该记录已经被删除\n");
                else
                {
                    while (getchar() != '\n');
                    while (printf("输入新的书名:"), gets(a[array_in].title) == NULL || a[array_in].title[0] == '\0');
                    while (printf("输入新的作者名:"), gets(a[array_in].author) == NULL || a[array_in].author[0] == '\0');
                    printf("输入新的价格:");
                    scanf("%f", &a[array_in].value);
                }
            }
            while (getchar() != '\n');
        }
    }
    f_write(a, arrays);
}

FILE * f_open(void)
{
    FILE *p_file;
    if ((p_file = fopen("books_s.dat", "a+b")) == NULL)
    {
        fprintf(stderr, "无法打开文件");
        exit(EXIT_FAILURE);
    }
    fseek(p_file, 0, SEEK_END);
    datas = ftell(p_file);

    return p_file;
}

void f_write(BOOKS a[], int arrays)
{
    FILE * p_file;
    int array_in;

    if ((p_file = fopen("books_s.dat", "w+b")) == NULL)
    {
        fprintf(stderr, "无法打开文件");
        exit(EXIT_FAILURE);
    }
    for (array_in = 0; array_in < arrays; array_in++)
        if (a[array_in].del_tag)
            fwrite(&a[array_in], sizeof(BOOKS), 1, p_file);
    datas = ftell(p_file);
    fclose(p_file);
}


[此贴子已经被作者于2017-1-31 15:20编辑过]

搜索更多相关主题的帖子: 管理程序 记录 
2017-01-30 01:51
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:7 
深夜睡不着~无聊来看帖~突然发现

int main(void)
{
    int n,i;
    long int k;
    FILE *fp;

    if((fp = fopen("books.dat","a+b")) == NULL)
    {
        fprintf(stderr,"无法打开文件");
        exit(EXIT_FAILURE);
    }
    fseek(fp,0,SEEK_END);
    k = ftell(fp);
    fclose(fp);
    printf("%d %d\n",k,n);

这段代码中n没有赋值~手机刷贴没有调试~不知有没有看错~

还有
    if((fp = fopen("books.dat","a+b")) == NULL)
a+b好像我还没见过耶~
fprintf(stderr,"无法打开文件");
stderr是什么意思呢~好像我的课外知识还不够广耶~
只是无聊粗略看看大致框架~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-01-30 02:02
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 2楼 九转星河
你说多出来的哪行以及变量n都是应该被删除的,我写来给我自己看的。
竟然留在那里了。

a+b是二进制打开文件,这样方便用结构体或者数组读取。
stderr是I/O标准错误,如果无法打开文件,就显示,好吧,其实在那里就跟printf差不多,不过对于打开文件的话,我习惯用fprintf,然后带上stderr.


[此贴子已经被作者于2017-1-30 02:12编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-01-30 02:07
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 2楼 九转星河
很多重复的代码,完全可以写另一个打开文件将数据复制到结构数组的函数来省掉不少,但是写的有点累了,后面的修改记录那个函数,直接复制的删除函数,稍加修改了一下。

[此贴子已经被作者于2017-1-30 02:56编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-01-30 02:09
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
得分:7 
闲着无聊,看了一遍。
读取直接用rb模式就行了,不必要用ab+模式
删除和修改直接用wb+模式,而且这两个函数是可以合在一个函数里。
2017-01-30 09:19
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 5楼 linlulu001
我知道,但是写的当时,完全没考虑,只想快点而弄完,以至于修改记录的函数完全就是复制的删除记录(只做了一点点修改)!这代码有很多地方可以精简。



[此贴子已经被作者于2017-1-30 13:21编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-01-30 12:11
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
得分:7 
具体的函数实现部分或许能够进一步精简。

不过楼主在main中广泛使用了函数指针,并不直接调用函数。能否指点一下这样做有什么好处?
{真心请教。我虽然知道函数指针是怎么回事,但是一值没怎么用上,也就遇到需要调用系统函数(比如排序神马的写qsort的comp函数)我也在一些人的代码中看到过类似的写法,但就是没人说过这有什么好处有点}  能不能讲讲,学习学习

φ(゜▽゜*)♪
2017-01-30 16:39
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 7楼 书生牛犊
其实就是顺手。
将函数将参数传递在后续的修改中会更方便,你可以直接修改函数就行,而不用修改其他。
比如说我定义的两个函数,xieru()和duqu(),如果在后面我要修改他们,我只需要直接修改这两个函数的定义,而不需要修改其他部分。



[此贴子已经被作者于2017-1-30 16:49编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-01-30 16:48
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
得分:0 
回复 8楼 renkejun1942
所以就是“封装”的意思?   好的,我在研究研究,谢谢

φ(゜▽゜*)♪
2017-01-30 16:50
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 7楼 书生牛犊
嗯……精简想不到,没有什么思路,但是有扩展的思路,总觉得有些地方不够完善,比如早上的时候就发现没有检查越界,后来加上了。

所以……导致,我修改了几次之后,代码量依旧没有减少。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-01-30 16:51



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-473884-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.371010 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved