我希望标题是正确的,抱歉,我无法更好地描述它。我有一个结构,其指针在程序的“会话”期间传播。当然,每次都抛出此结构,所以我想将当前状态保存到二进制文件中。因为entry:data是指向未知长度数组的指针,所以我尝试将长度附加到每个条目。到目前为止,一切工作正常,但是当我想删除或添加antry时,我遇到了问题。我想创建一个(struct entry)数组,其长度在文件头中,但是一旦我创建struct,该函数就不再起作用了。
这是一个最小的工作示例
#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;
}
答案 0 :(得分: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
。原始代码不必要地使用了&data
和fread
中的printf
。另外,看起来数据实际上并没有读入entry
的列表中,这似乎很奇怪。
警告
此代码分配了内存,用户有责任在程序结束前释放内存。