繁体   English   中英

如何将文件中的结构读入数组,修改并写回?

[英]How to read structures from a file into an array, modify it and write it back?

我希望标题是正确的,我无法更好地描述它,抱歉。 我有一个带有在程序“会话”期间传播的指针的结构。 当然,每次都会抛出这个结构,所以我想将当前状态保存到一个二进制文件中。 因为 entry:data 是一个指向未知长度数组的指针,所以我尝试将长度附加到每个条目。 到目前为止一切正常,但是当我想删除或附加一个 antry 时,我遇到了问题。 我想创建一个(结构体条目)的数组,其长度在文件头中,但是一旦我创建了结构体,该函数就不再起作用了。

这是一个最小的工作示例

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

struct header {
    int id;
    int len;
};

struct entry {
    int id;       
    int len; // length of data        
    char *data;   
};

void createNewStorage() {

    FILE *f = fopen("test.bin", "wb");   

    // create a header with id=1 and len=2 
    struct header hdr = {1, 2};
    fwrite(&hdr, sizeof(struct header), 1, f);

    char *data;

    data = "This is some data of unknown length, i hope it works";
    int id = 1;
    int len = strlen(data);    
    struct entry e = {id, len, data};
    fwrite(&e.id, sizeof(int), 1, f);
    fwrite(&e.len, sizeof(int), 1, f);
    fwrite(e.data, sizeof(char), strlen(e.data), f);

    id = 2; 
    data = "\x01\x12\x23"; 
    len = strlen(data); 
    e.id = id;
    e.data = data;
    e.len = len;
    fwrite(&e.id, sizeof(int), 1, f);
    fwrite(&e.len, sizeof(int), 1, f);
    fwrite(e.data, sizeof(char), e.len, f);

    fclose(f);

}

void appendNewEntry() {

    FILE *f = fopen("test.bin", "rb");       

    // get the header
    struct header hdr;
    fread(&hdr.id, sizeof(int), 1, f);
    fread(&hdr.len, sizeof(int), 1, f);
    printf("hdr: id='%d', len='%d'\n", hdr.id, hdr.len);

    // get the entries
    int id, len = 0; char *data; 
    int i = 0;
    while(i < hdr.len) {    
        fread(&id, sizeof(int), 1, f);
        fread(&len, sizeof(int), 1, f);
        fread(&data, sizeof(char), len, f);
        printf("entry: id='%d', len='%d', data='%s'\n", id, len, &data);
        i++;        
    }    
    printf("Done..\n");
    fclose(f);

}

int main(void){
    createNewStorage();
    appendNewEntry();
    return 0;
}

先感谢您。

编辑:最后我让它工作了,这是最终的代码。

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

struct header {
    int id;
    int len;
};

struct entry {
    int id;       
    int len; // length of data        
    char *data;   
};

void create() {
    FILE *f = fopen("test.bin", "wb");   
    // create a header with id=1 and len=2 
    struct header hdr = {1, 2};
    fwrite(&hdr, sizeof(struct header), 1, f);
    char *data;
    data = "This is some data of unknown length, i hope it works";
    int id = 1;
    int len = strlen(data);    
    struct entry e = {id, len, data};
    fwrite(&e.id, sizeof(int), 1, f);
    fwrite(&e.len, sizeof(int), 1, f);
    fwrite(e.data, sizeof(char), strlen(e.data), f);
    id = 2; 
    data = "\x01\x12\x23"; 
    len = strlen(data); 
    e.id = id;
    e.data = data;
    e.len = len;
    fwrite(&e.id, sizeof(int), 1, f);
    fwrite(&e.len, sizeof(int), 1, f);
    fwrite(e.data, sizeof(char), e.len, f);
    fclose(f);
}

void modify() {
    FILE *f = fopen("test.bin", "rb");       
    // get the header
    struct header hdr;
    fread(&hdr.id, sizeof(int), 1, f);
    fread(&hdr.len, sizeof(int), 1, f);
    printf("Reading storage hdr: id='%d', len='%d' ", hdr.id, hdr.len);
    // create a new list to store all existing entries
    struct entry list[hdr.len];    
    // get the entries
    int id, len = 0; char *data; 
    int i = 0;
    while(i < hdr.len) {    
        fread(&id, sizeof(int), 1, f);
        fread(&len, sizeof(int), 1, f);
        data = malloc((len + 1) * sizeof(char));
        fread(data, sizeof(char), len, f);
        data[len] = '\0';
        //printf("entry: id='%d', len='%d', data='%s'\n", id, len, &data[0]);
        struct entry e = {id, len, data};
        list[i] = e;
        i++;        
    }    
    printf("Done..\n");
    printf("The list has %d entries\n", i);
    int il = 0;
    while(il < i) {
        printf("entry %d: len='%d', data='%s'\n", il, list[il].len, list[il].data);
        il++;
    }    
    fclose(f);
}

void append(char *newdata) {
    printf("Appending new data..\n");
    FILE *f = fopen("test.bin", "rb");       
    // get the header
    struct header hdr;
    fread(&hdr.id, sizeof(int), 1, f);
    fread(&hdr.len, sizeof(int), 1, f);
    printf("Reading storage hdr: id='%d', len='%d' ", hdr.id, hdr.len);
    // create a new list to store all existing entries
    struct entry list[hdr.len];    
    // get the entries
    int id, len = 0; char *data; 
    int i = 0;
    while(i < hdr.len) {    
        fread(&id, sizeof(int), 1, f);
        fread(&len, sizeof(int), 1, f);
        data = malloc((len + 1) * sizeof(char));
        fread(data, sizeof(char), len, f);
        data[len] = '\0';
        //printf("entry: id='%d', len='%d', data='%s'\n", id, len, &data[0]);
        struct entry e = {id, len, data};
        list[i] = e;
        i++;        
    }    
    printf("Done..\n");
    /*
    printf("The list has %d entries\n", i);
    int il = 0;
    while(il < i) {
        printf("entry %d: len='%d', data='%s'\n", il, list[il].len, list[il].data);
        il++;
    }
    */
    fclose(f);    
    f = fopen("test.bin", "wb");    
    struct header outhdr = {hdr.id, hdr.len+1};
    fwrite(&outhdr, sizeof(struct header), 1, f);    
    int il = 0;
    while(il < i) {
        printf("writing entry %d\n", il, list[il].len, list[il].data);
        fwrite(&list[il].id, sizeof(int), 1, f);
        fwrite(&list[il].len, sizeof(int), 1, f);
        fwrite(&list[il].data[0], sizeof(char), list[il].len, f);
        il++;
    }
    il++;
    struct entry e;
    int nid = il;  
    int nlen = strlen(newdata); 
    e.id = nid;
    e.data = newdata;
    e.len = nlen;
    printf("writing new entry\n");
    fwrite(&e.id, sizeof(int), 1, f);
    fwrite(&e.len, sizeof(int), 1, f);
    fwrite(e.data, sizeof(char), e.len, f);        
    fclose(f);    
}

void erase(int entryId) {
    printf("Appending new data..\n");
    FILE *f = fopen("test.bin", "rb");       
    // get the header
    struct header hdr;
    fread(&hdr.id, sizeof(int), 1, f);
    fread(&hdr.len, sizeof(int), 1, f);
    printf("Reading storage hdr: id='%d', len='%d' ", hdr.id, hdr.len);
    // create a new list to store all existing entries
    struct entry list[hdr.len];    
    // get the entries
    int id, len = 0; char *data; 
    int i = 0;
    while(i < hdr.len) {    
        fread(&id, sizeof(int), 1, f);
        fread(&len, sizeof(int), 1, f);
        data = malloc((len + 1) * sizeof(char));
        fread(data, sizeof(char), len, f);
        data[len] = '\0';
        //printf("entry: id='%d', len='%d', data='%s'\n", id, len, &data[0]);
        struct entry e = {id, len, data};
        list[i] = e;
        i++;        
    }    
    printf("Done..\n");
    /*
    printf("The list has %d entries\n", i);
    int il = 0;
    while(il < i) {
        printf("entry %d: len='%d', data='%s'\n", il, list[il].len, list[il].data);
        il++;
    }
    */
    fclose(f);
    f = fopen("test.bin", "wb");    
    struct header outhdr = {hdr.id, hdr.len-1};
    fwrite(&outhdr, sizeof(struct header), 1, f);    
    int il = 0;
    while(il < i) {
        if(list[il].id == entryId) {
            // this is the one to delete
            //printf("THIS IS IT -> %d\n", il);
        } else {
            printf("writing entry %d\n", il, list[il].len, list[il].data);
            fwrite(&list[il].id, sizeof(int), 1, f);
            fwrite(&list[il].len, sizeof(int), 1, f);
            fwrite(&list[il].data[0], sizeof(char), list[il].len, f);
        }
        il++;
    }       
}

int main(void){

    create();

    getch();

    char *input;
    input = "Mein Hund ist der aller aller Beste";
    append(input);

    getch();

    erase(1);

    return 0;
}

尝试这个:

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

struct header {
    int id;
    int len;
};

struct entry {
    int id;
    int len; // length of data
    char *data;
};

void createNewStorage() {

    FILE *f = fopen("test.bin", "wb");

    // create a header with id=1 and len=2
    struct header hdr = {1, 2};
    fwrite(&hdr, sizeof(struct header), 1, f);

    char *data;

    data = "This is some data of unknown length, i hope it works";
    int id = 1;
    int len = strlen(data);
    struct entry e = {id, len, data};
    fwrite(&e.id, sizeof(int), 1, f);
    fwrite(&e.len, sizeof(int), 1, f);
    fwrite(e.data, sizeof(char), strlen(e.data), f);

    id = 2;
    data = "\x01\x12\x23";
    len = strlen(data);
    e.id = id;
    e.data = data;
    e.len = len;
    fwrite(&e.id, sizeof(int), 1, f);
    fwrite(&e.len, sizeof(int), 1, f);
    fwrite(e.data, sizeof(char), e.len, f);

    fclose(f);

}

void appendNewEntry() {

    FILE *f = fopen("test.bin", "rb");

    // get the header
    struct header hdr;
    fread(&hdr.id, sizeof(int), 1, f);
    fread(&hdr.len, sizeof(int), 1, f);
    printf("hdr: id='%d', len='%d'\n", hdr.id, hdr.len);

    // get the entries
    int id, len = 0; char *data;
    int i = 0;
    while(i < hdr.len) {
        fread(&id, sizeof(int), 1, f);
        fread(&len, sizeof(int), 1, f);
        data = malloc((len + 1) * sizeof(char));
        fread(data, sizeof(char), len, f);
        data[len] = '\0';
        printf("entry: id='%d', len='%d', data='%s'\n", id, len, data);
        i++;
    }
    printf("Done..\n");
    fclose(f);

}

int main(void){
    createNewStorage();
    appendNewEntry();
    return 0;
}

输出

hdr: id='1', len='2'
entry: id='1', len='52', data='This is some data of unknown length, i hope it works'
entry: id='2', len='3', data='#'
Done..

笔记

我必须添加#inlude <stdlib.h>才能使用malloc 原始代码在freadprintf不必要地使用&data 此外,看起来数据实际上并没有被读入一个entry列表,这看起来很奇怪。

警告

此代码分配内存,用户有责任在程序结束前释放内存。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM