首页 > 解决方案 > 基于 C 中的密钥更新文件

问题描述

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

struct person 
{
    char  name[10];
    char size[6];
    char timestamp[15];
};
  
int main ()
{
    FILE *outfile;
      
    // open file for writing
    outfile = fopen ("ads.txt", "a");
    if (outfile == NULL)
    {
        fprintf(stderr, "\nError opend file\n");
        exit (1);
    }
  
    struct person input1 = {"runner", "100", "4376482682"};
    //struct person input2 = {"maze", "300", "3232365436"};
      
    // write struct to file
    fwrite (&input1, sizeof(struct person), 1, outfile);
    //fwrite (&input2, sizeof(struct person), 1, outfile);
      
    if(fwrite != 0) 
        printf("contents to file written successfully !\n");
    else 
        printf("error writing file !\n");
  
    // close file
    fclose (outfile);
  

     FILE *infile;
    struct person input;

    infile = fopen ("ads.txt", "r");
    if (infile == NULL)
    {
        fprintf(stderr, "\nError opening file\n");
        exit (1);
    }
      
    // read file contents till end of file
    char name[10] = "maze";
    char size[6] = "500";
    char timestamp[15] = "437838322";
    int remaining_size = 100;
    int alreadythere =0;
    //unpcoming file size
    int incoming_file_size = 200;
    int target_file_size_toremove = incoming_file_size - remaining_size;
    while(fread(&input, sizeof(struct person), 1, infile)){
        if(target_file_size_toremove > 0) {
            int x = atoi(input.size);
            if(target_file_size_toremove < x) {
                strcpy(input.name, name);
                strcpy(input.size, size);
                strcpy(input.timestamp, timestamp);
            }
        }else {
        if(strcmp(input.name, name) == 0) { // if name is eqUAL
            if(strcmp(input.size, size) != 0) {
                strcpy(input.size, size);
            }
            if(strcmp(input.timestamp, timestamp) !=0) {
                strcpy(input.timestamp, timestamp);
            }
        alreadythere = 1;
        }
        printf ("id = %s name = %s %s\n", input.name,
        input.size, input.timestamp);
    }
    }
    if(alreadythere == 0) {
        struct person incoming = {name, size, timestamp};
        fwrite (&incoming, sizeof(struct person), 1, outfile);
    }
    // close file
    fclose (infile);
    return 0;
}

代码是C语言的。我想size在名称等于“迷宫”时更新变量。从文件中读取时,我该怎么做?

首先写入文件的数据是 -
runner 100 4376482682 maze 300 3232365436

更新后 -
runner 100 4376482682
maze 100 3232365436

大小应该从 300 更新到 100。

标签: cfile-handling

解决方案


我已经修复了您的代码中的一些小错误,这些错误与以正确模式打开文件并检查是否成功fwrite以及fread在哪里成功有关。然后我添加了你真正要求的部分:更新记录“迷宫”。

要更新记录,我们需要读取它,更改值并将其写回到我们读取它的确切位置。因此,在读取记录之前,我们查询当前文件指针,ftell在写入之前,我们调用fseek将文件指针移回我们读取的位置。需要调用fflush(另一个fseek也可以),以便下一个fread发生在正确的位置。

为了测试,我在“迷宫”之后添加了第三条记录,以便我们可以通过查看文件内容看到我们不会覆盖数据。

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

struct person
{
    char name[10];
    char size[6];
    char timestamp[15];
};

int main()
{
    FILE* outfile;

    // open file for writing binary
    outfile = fopen("ads.txt", "wb");  
    if (outfile == NULL) {
        fprintf(stderr, "\nError opening file\n");
        exit(1);
    }

    struct person input1 = { "runner", "100", "4376482682" };
    struct person input2 = { "maze",   "300", "3232365436" };
    struct person input3 = { "street", "400", "4232365486" };

    // write struct to file, checking for success
    if ((fwrite(&input1, sizeof(struct person), 1, outfile) != 1) ||
        (fwrite(&input2, sizeof(struct person), 1, outfile) != 1) ||
        (fwrite(&input3, sizeof(struct person), 1, outfile) != 1))
        printf("error writing file !\n");
    else
        printf("contents to file written successfully !\n");

    // close file
    fclose(outfile);


    FILE* infile;
    struct person input;

    // Open for both reading and writing, binary
    infile = fopen("ads.txt", "r+b");
    if (infile == NULL) {
        fprintf(stderr, "\nError opening file for update\n");
        exit(1);
    }

    // read file contents till end of file, update "maze"
    while (1) {
        long pos = ftell(infile);
        if (pos < 0) {
            fprintf(stderr, "\nError getting file position\n");
            break;
        }
        if (fread(&input, sizeof(struct person), 1, infile) != 1)
            break;
        // update the value of size here, if name is equal to "maze"
        printf("id = %s name = %s %s\n", input.name, input.size, input.timestamp);
        if (strcmp(input.name, "maze") == 0) {
            if (fseek(infile, pos, SEEK_SET) != 0) {
                fprintf(stderr, "\nError moving file pointer\n");
                break;
            }
            strcpy(input.size, "100");
            if (fwrite(&input, sizeof(struct person), 1, infile) != 1) {
                fprintf(stderr, "\nError writing file\n");
                break;
            }
            // fflush() is required so that fread() take place a the correct position
            if (fflush(infile) != 0) {
                fprintf(stderr, "\nError flushing file\n");
                break;
            }
            printf("  Updated id = %s name = %s %s\n", input.name, input.size, input.timestamp);
            // Since this code update a single record, we could break the loop
        }
    }

    // close file
    fclose(infile);
    return 0;
}

推荐阅读