【发布时间】:2020-04-12 12:20:10
【问题描述】:
我希望标题是正确的,我无法更好地描述它,对不起。我有一个带有在程序“会话”期间传播的指针的结构。当然,每次都会抛出这个结构,所以我想将当前状态保存到二进制文件中。因为 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;
}
【问题讨论】:
-
您能否更详细地描述一下“不起作用”对您的程序意味着什么?预期结果和实际结果是什么?
-
'不起作用'意味着它只是停止了。你试过重现它吗?对你起作用吗?在我的电脑上,光标图标弹出加载光标,然后控制台崩溃。真的,我无话可说。
-
您没有提供minimal verifiable example,因此很难尝试。请这样做。
-
在调试器中运行它,它可以立即指出问题所在:
fread(&data[0], sizeof(char), len, f);它在该行出现问题。这给你任何线索吗? -
在继续之前,请使用
gcc -Wall -Werror -o program program.c编译您的代码,并将program替换为您的实际文件名。这将显示大多数警告并将警告视为错误。也就是说,在修复导致警告的代码之前,您将无法运行代码。