【问题标题】:save a file modified using a list (c language)保存使用列表修改的文件(c语言)
【发布时间】:2021-08-18 18:49:23
【问题描述】:

================================================ ===============
编辑:对不起,我好像没有解释清楚
我的程序所做的是
open file for reading => load list from the file => operations chosen by user will be applies to list (not file)(add-search-display-reset)\ => import change to file(如果有的话)
如果用户选择仅添加员工并退出 will it be better 以将添加的节点附加到文件末尾,则关闭并释放列表 or 可以打开文件以读取并覆盖开始时的所有节点
这最后一个选项将为我节省大量代码行,但它会在执行时为用户节省时间和精力吗?

================================================ ===============

我正在处理一个(c 语言)学校项目,我们必须同时使用 listsfiles 来:

  • 显示员工列表
  • 添加员工
  • 搜索员工
  • 重置列表
  • 保存并退出

所以我正在寻找最好的方法,据我所知,好的代码是确保程序尽可能使用 less memory 并尽可能使用 fast 的代码。
我要问的是
打开包含员工信息的文件并将其加载到列表中,并通过addreset修改列表后,会不会更好:

  • 为“w”打开文件并用列表填充它。
  • 或打开它以“a+”从最后一名员工添加。

请注意,最后一种方式我必须记住 initial_number_of_lines(又名节点)并查找“初始最后一个节点”以开始加载。
注意:employee变量是first_namelast_namesalary; VERIFY(file) 返回 1 我打开的文件如果没有返回 0;

void load_file(list *list, char *filename)
{
    if (current_number_of_lines != initial_number_of_lines || list_reset == 1)
    {
        if (current_number_of_lines > initial_number_of_lines && list_reset == 0)
        {
            FILE *file = fopen(filename, "a+");
            if (VERIFY(file) == 1)
            {
                for (int i = 0; i < initial_number_of_lines; i++)
                {
                    list = list->next;
                }
                while (list != NULL)
                {
                    fprintf(file, "%s\t%s\t%lf\n", list->emp.Fname, list->emp.Lname, list->emp.salary);
                    list = list->next;
                }
            }
            fclose(file);
        }
        else if (list_reset == 1)
        {
            FILE *file = fopen(filename, "w");
            while (list != NULL)
            {
                fprintf(file, "%s\t%s\t%lf\n", list->emp.Fname, list->emp.Lname, list->emp.salary);
                list = list->next;
            }
            fclose(file);
        }
        else
            printf("Error\n");
    }
    freeList(list);
}

【问题讨论】:

  • 如果删除元素,则必须重写文件。
  • 对我来说奇怪的是,当代码写入文件时,函数名称是load_file。
  • 编辑了我的答案以根据您对问题的更改给出提示。请再次阅读我的回答。

标签: c list file memory complexity-theory


【解决方案1】:

如果您的所有add 操作都将新节点添加到列表末尾,则使用a+ 将获得更好的性能。另一方面,如果你总是重写整个文件,代码会更简单。那么对你来说最重要的是什么?性能还是简单的代码?我将从简单的方法开始。

其他一些注释。

在实际写入文件时调用函数load_file,这很奇怪。

变量:current_number_of_linesinitial_number_of_lineslist_reset 似乎是全局变量。应该避免使用全局变量。

逻辑(又名if 语句)似乎太复杂了。你可以这样做:

void load_file(list *list, char *filename)
{
    if (list_reset == 1)
    {
        ...
    }
    else if (current_number_of_lines > initial_number_of_lines)
    {
        ...
    }
    else if (current_number_of_lines < initial_number_of_lines)
    {
        printf("Error\n");
    }
    freeList(list);
}

【讨论】:

    【解决方案2】:

    如果你在 fopen() 中使用“w”,那么它会将文件截断为零长度或创建文本文件进行写入。流位于文件的开头。您必须将所有记录写入文件。

    如果你对 fopen() 使用“a+”,那么文件将被打开以供读取和追加(在文件末尾写入)。如果文件不存在,则创建该文件。输出总是附加到文件的末尾。警告:POSIX 对使用此模式时的初始读取位置保持沉默。在该模式下,您只会写入需要添加的记录。

    还请注意,这两种方法都不适合在两个或多个应用程序之间共享数据。

    如果在列表末尾添加新记录,显然将这些记录追加到文件末尾会更快(“a+”模式)。

    由于您有一个文本文件(由文本行组成),很遗憾无法更新已更改的记录。在这种情况下,您必须将列表中的所有内容写入文件(“w”模式)。

    如果您更改文件格式以使用固定大小的记录,则可以通过将文件定位在记录上然后写入来优化写入。为此,您将记录定义为包含固定大小字符串的结构。当然,在该结构中添加一个项目以记住它是从列表中读取的位置。

    【讨论】:

    • @omayma 你看到我的回答了吗?如果有帮助,请使用我的答案左侧的勾号将其标记为已接受。
    猜你喜欢
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多