如何覆盖文本文件中的内容? (编辑项目)

时间:2016-06-15 05:59:12

标签: c

我的问题是,当我输入项目代码时,如何编辑字符串值让我们举例说:(这是在一个名为gst.txt的文本文件中)

AG001;July biscuits;5.35;90
BG001;Maximu Bun;3.50;20 
BG002;Lamli Burger;4.60;15
CG001;TTT Candy;4.00;42
CG002;Cappuccino;7.80;30
CG003;Queenz Cakes;14.00;5
DG001;Donkey Donuts;3.80;24
DG002;French Fries;4.30;11

该段如下:(itemcode);(itemname);(itemprice);(itemquantity)

当我输入AG001的商品代码时。我可以选择是否编辑项目名称,项目数量的项目价格。当我选择项目名称选项时,我输入了项目的新名称。如何在仅更改文本文件的该段时,将现有July biscuits覆盖为Gardenia之类的内容?

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char itemcode[10];
char gst[256];
char gstcode[10], gstname[50];
char gstprice[10];
char gstquantity[5];
char selection[5];
char newname[50], newprice[10], newquantity[5];

int main()
{
    FILE* fgst;
    fgst = fopen("gst.txt", "r+");

    while (strcmp(itemcode, "-1") != 0) {

        printf("Enter item code to be edited <-1 to exit>: ");
        scanf("%s", itemcode);

        if (strcmp(itemcode, "-1") == 0)
            break;

        if (strcmp(itemcode, "AG001") == 0 || strcmp(itemcode, "BG001") == 0 || strcmp(itemcode, "BG002") == 0 || strcmp(itemcode, "CG001") == 0 || strcmp(itemcode, "CG002") == 0 || strcmp(itemcode, "CG003") == 0 || strcmp(itemcode, "DG001") == 0 || strcmp(itemcode, "DG002") == 0) {

            while (fgets(gst, 256, fgst) != NULL) {

                sscanf(gst, "%5[^;];%29[^;];%10[^;];%5[^;]", gstcode, gstname, gstprice, gstquantity);

                if (strcmp(itemcode, gstcode) == 0) {

                    printf("Enter <1> to edit item name, <2> for price, <3> for quantity: ");
                    scanf("%s", selection);

                    if (strcmp(selection, "1") == 0) {

                        printf("Enter the new item name: ");
                        scanf("%s", newname);
                        fprintf(fgst, "%s;%s;%s;%s", gstcode, newname, gstprice, gstquantity);
                        break;
                    }
                    else if (strcmp(selection, "2") == 0) {

                        printf("Enter the new item price: ");
                        scanf("%s", newprice);
                        fprintf(fgst, "%s;%s;%s;%s", gstcode, gstname, newprice, gstquantity);
                        break;
                    }

                    else if (strcmp(selection, "3") == 0) {

                        printf("Enter the new item quantity: ");
                        scanf("%s", newquantity);
                        fprintf(fgst, "%s;%s;%s;%s", gstcode, gstname, gstprice, newquantity);
                        break;
                    }

                    else {
                        printf("Invalid input.");
                    }
                }
            }
        }
        else {

            printf("Item not found.\n");
            printf("Re-enter the correct item code.\n");
        }
    }
}

2 个答案:

答案 0 :(得分:0)

正如iharob所建议的那样,您可能需要创建一个临时文件,将修改后的内容写入其中并重命名。它适用于大多数情况。

但是,如果这涉及数千或数十万个条目,则此方法不实用。然后,您将需要一个不同的文件存储结构。每个字段都应该有一个最大限制并填充到它的限制。在每种情况下,每条线的大小将相等,并且可以很容易地被另一条线替换。

e.g。

AG001;July biscuits      ;005.035;090
BG001;Maximu Bun         ;003.050;020 
BG002;Lamli Burger       ;004.060;015
CG001;TTT Candy          ;004.000;042

答案 1 :(得分:0)

我做了一个简单的例子,向您展示如何使用结构和一个临时的&#39;文件来实现你的目标。

这是您商品的短端结构。为简单起见,我只使用了项目代码和项目名称:

typedef struct
{
  char item_code[10];
  char item_name[50];
} item;

首先,我建议写一个写函数,这样你就可以轻松地将这个结构写入文件并从中读取。像这样:

void write_items_to_file(FILE* fp, item* items, size_t size)
{
  if (!fp)
  {
    fprintf(stderr, "File not open!\n");
    return;
  }

  for (size_t i = 0; i < size; i++)
  {
    fprintf(fp, "%s;%s;\n", items[i].item_code, items[i].item_name);
  }
}

size_t read_items_from_file(FILE* fp, item* items, size_t max)
{
  if (!fp)
  {
    printf("File not open!\n");
    return -1;
  }

  char line[MAX_LEN];
  size_t current_item = 0;
  while (fgets(line, MAX_LEN, fp) && current_item < max)
  {
    if (sscanf(line, "%5[^;];%50[^;];", (items[current_item].item_code), (items[current_item].item_name)) != 2) // change '2' to the amount of atributes of item
    {
      fprintf(stderr, "Wrong internal file organization!\n");
      return -2;
    }
    current_item++;
  }
  return current_item;
}

现在我们得到了这个,让我们面对变化的部分。假设我们有一个包含两个项目的文件:

AG001;July biscuits;
BG001;Maximu Bun;

现在我们可以使用read_items_from_file函数来获取项目。如果您现在想要将July biscuits更改为Gardenia,我们可以使用strncmp查找名称为July biscuits的项目并替换它。

当我们完成编辑项目后,我们会将其写入另一个文件,例如"items.txt.tmp"使用write_items_to_file函数。之后我们rename临时&#39;文件到原始文件,因此替换原始文件中所需项目的名称。这是其他人指出最简单的方法。

这是我描述的场景的完整主要内容:

int main()
{
  FILE *fp = fopen("items.txt", "r");
  item items_read[2]; 

  size_t read_values = read_items_from_file(fp, items_read, 2);

  for (size_t i = 0; i < read_values; i++)
  {
    if (strncmp(items_read[i].item_name, "July biscuits", 50) == 0)
    {
      strncpy(items_read[i].item_name,"Gardenia", 50);
    }
  }

  if (fp)
  {
    fclose(fp);
  }

  // now create a new file
  fp = fopen("items.txt.tmp", "w");
  if (fp)
  {
    write_items_to_file(fp, items_read, 2);
    fclose(fp);

    // now "move" the temp file to the original file using 'rename'
    rename("items.txt.tmp", "items.txt");
  }
}

注意:当然,您必须根据您的要求更改item struct以及读写功能。