【问题标题】:The .txt does not correctly edit the text - C.txt 没有正确编辑文本 - C
【发布时间】:2022-01-21 14:36:27
【问题描述】:

我的 .txt 文件有问题,因为我必须创建客户记录,然后才能更改数据。会发生以下情况,当我创建客户端时,数据如下所示:

enter image description here

但是当我去编辑名称或国家时,就是这样,而我想要你在不创建新行的情况下进行更改。

  • 姓名:

enter image description here

  • 国家:

enter image description here

我可能遗漏了什么或者这是保存文件的方法,但我不知道!!

这是我的代码:

typedef struct {
    char name[80];
    char country[10];
    int tin;
    int customer_code;
} CLIENT, upd, add;

void
edit_customer()
{

    CLIENT add, upd;
    int choice;
    FILE *bd;

    bd = fopen("bd.txt", "a");
    printf("Enter the customer code: ");
    scanf("%d", &add.customer_code);

    printf("\nSelect the type of change you want:\n1 - Name\n2 - Country\n\nEnter your choice:");
    scanf("%d", &choice);

    switch (choice) {
    case 1:
        fgets(upd.name, 80, stdin);
        printf("Type your name: ");
        scanf("%[^\n]s", upd.name);
        fprintf(bd, "code: %d | name: %s | tin: %d | country: %s \n",
            add.customer_code, upd.name, add.tin, add.country);

        printf("Changes saved!");
        break;
    case 2:
        printf("Enter the Country:");
        scanf("%s", upd.country);
        fprintf(bd, "code: %d | name: %s | tin: %i | country: %s \n",
            add.customer_code, add.name, add.tin, upd.country);
        printf("Changes saved!");
        break;
    }

}

【问题讨论】:

  • 请不要发布链接图片的文本。请编辑您的问题,然后从调试/控制台窗口复制并粘贴到此处的代码块中。
  • 你有 UB(未定义的行为)。 struct updundefined。当您在 either case 中执行 scanf 时,other 字段未定义。 (例如)对于case 1:,它定义了upd.name,但其他字段upd.country 是随机的。另外,请注意您为upd 执行scanf,但为add 执行printf,这是另一个错误。
  • 回复:%[^\n]s; %[]%s 是不同的格式说明符。您不需要将它们组合起来。

标签: c


【解决方案1】:

更新文件中的数据并不容易。首先,您必须决定您打算如何保存数据,因为您修改数据的方式将取决于此。有很多方法可以做到这一点,但为了简单起见,有两种基本方法。第一种方法是插入固定大小的记录。实际上,您必须确定记录的每个字段的大小,并且对于文件的所有记录,它必须始终相同。所以,以你的结构为例

typedef struct {
    char name[80];
    char country[10];
    int tin;
    int customer_code;
} CLIENT;

您可以通过稍微修改fprintf的格式来写入记录,例如:

"| code: %-10u | name: %-20.20s | tin: %-10u | country: %-25.25s |\n"

这样您的文件将包含这样的记录(知道它们在记录中的位置,您实际上并不需要字段名称):

| code: 1234561    | name: Super Mario          | tin: 1286608618 | country: know the name             |
| code: 23         | name: John                 | tin: 123        | country: Donknow                   |

现在,如果您想修改存在的记录之一,则必须通过逐行读取并保存在文件中搜索它,在每次读取之前,使用例如 @987654325 在文件中开始行的位置@ 功能。找到记录,加载其字段并修改您要更改的字段,此时将文件指针移回行首(fseek 函数)并用刚刚修改的记录覆盖旧记录。

另一方面,如果您不想使用固定大小的记录,就像您现在所做的那样,工作会变得有点复杂,因为不幸的是文件没有弹性化,所以如果您需要修改记录它的长度与文件中的长度不同,您必须为其腾出空间。有上千种方法可以做到这一点,但本质上你应该:

  • 将要修改的记录保存在文件中
  • 修改记录
  • 在您编辑的记录末尾剪切文件
  • 将您之前保存的部分附加到文件中

实际上,为了安全起见,您应该:

  • 创建一个临时文件
  • 将要修改的记录之前的记录复制到临时文件中
  • 追加新记录
  • 附加文件的其余部分,旧记录除外
  • 保存临时文件 (fclose)
  • 删除旧文件
  • 用刚刚删除的文件名重命名临时文件

除此之外,正如 cmets 所说,在您的程序中,您尝试修改尚未从文件中读取的记录,因此用户修改的字段是唯一具有值的字段,而其他字段则没有被初始化。然而,这还不够。如果您想看到您的程序正常运行,您必须按照我写给您的内容进行操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多