我有这个结构
struct _recipe
{
char name[50];
char** ingredients;
char diff[12];
int time;
int calories;
char** procedure;
} recipe;
我想将所有数据复制到二进制文件中。 首先,我已经为成分和过程动态分配了内存,并编写了所需的全部内容。但是然后我需要将所有内容都写入一个二进制文件中。我知道它们都是指针,所以这意味着如果我使用
fwrite(&recipe,sizeof(recipe),1,fbr);
我将在文件中写入地址,而不是我需要的实际值。我尝试用这种方式将struct的每个字段写入文件
fwrite(recipe.name,sizeof(recipe.name),1,fbr);
fgets(recipe.ingredients[j],30,stdin);
strcpy(buff,recipe.ingredients[j]);
len = strlen(buff);
fwrite(buff,sizeof(recipe.ingredients[0]),len,fbr);
fwrite(recipe.diff,sizeof(recipe.diff),1,fbr);
fwrite(&recipe.time,sizeof(recipe.time),1,fbr);
fwrite(&recipe.calories,sizeof(recipe.calories),1,fbr);
fgets(recipe.procedure[i],1000,stdin);
strcpy(buff,recipe.procedure[i]);
len = strlen(buff);
fwrite(buff,sizeof(recipe.procedure[0]),len,fbr);
我不确定这是正确的方法,但是我尝试将字符串放入另一个字符串中,然后将其复制到文件中。问题是,我不确定它是否有效,因为我不知道应该使用哪种命令读取存储的所有值。以它的名字当然有效,我对此没有任何问题,但是当我要阅读成分时,我封锁了自己,因为我在另一个字符串中写了该值,而且我不知道应该输入多少长度阅读。也许我缺少了一些东西,也许我一开始就很在意写作,但此时我不知道该怎么办。
答案 0 :(得分:0)
您想要执行以下操作来写出您的食谱:
fwrite(recipe.name,sizeof(recipe.name),1,fbr);
for (int i = 0; i < num_ingredients; i++) {
int len = strlen(recipe.ingredients[i]) + 1;
int num_elements = fwrite(recipe.ingredients[i],sizeof(char),len,fbr);
printf("wrote %d elements for %s\n", num_elements, recipe.ingredients[i]);
}
fwrite(recipe.diff,sizeof(recipe.diff),1,fbr);
for (int i = 0; i < num_procedures; i++) {
int len = strlen(recipe.procedure[i]) + 1;
int num_elements = fwrite(recipe.procedure[i],sizeof(char),len,fbr);
printf("wrote %d elements for %s\n", num_elements, recipe.procedure[i]);
}
当然,您还需要写出卡路里和时间。在将任何内容读入struct之前,我也会这样做:
memset(&recipe, 0, sizeof(struct _recipe));
如果您使用fprintf用\n
来写出卡路里和时间,并使用分隔符,则配方文件将如下所示:
$ od -c recipe.bin
0000000 m u f f i n s \0 \0 \0 \0 \0 \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0000060 \0 \0 f l o u r \0 s u g a r \0 e g
0000100 g s \0 v a n i l l a \0 n u t s \0
0000120 n o d i f f \0 \0 \0 \0 \0 m i x \0
0000140 b a k e \0 r e s t \0 6 0 \n 2 5 0
0000160 \n
答案 1 :(得分:0)
您可以设计一个简单的存储protocol
来进行读写。
例如:
| struct recipe | t l v | t l v | ... | t l v | struct recipe | t l v | ... | t l v |
|<- a complete struct recipe data ->|
| description | t(ype) | l(ength) | v(alue)|
| ingredient | i | strlen() | string |
| procedure | p | strlen() | string |
| data end | e | 0 | <null> |
读取配方数据:
1. Read a struct recipe.
2. Read a t, t=='i' -- go (3.), t=='p' -- go (4.), t=='e' -- go (5.).
3. Read a l, then read a string whose length is l as an ingredient. Go (2.).
4. Read a l, then read a string whose length is l as a procedure. Go (2.).
5. Finish.
写入配方数据:
1. Write a struct recipe.
2. Write ingredients to `i strlen(ingredient) ingredient` one by one.
3. Write procedures to `p strlen(procedure) procedure` one by one.
4. Write `e 0`.
5. Finish.
伪代码:(只是一个演示,请设计自己的protol-
)
void write_recipe(recipe *r, FILE *fp)
{
fwrite(r, sizeof(recipe), 1, fp);
// ...
for ()
{
sprintf(buff, "i %5d %s", strlen(r->ingredients[i]), r->ingredients[i]);
fwrite(buff, strlen(buff), 1, fp);
}
sprintf(buff, "e 0");
fwrite(buff, strlen(buff), 1, fp);
//...
for ()
{
sprintf(buff, "p %5d %s", strlen(r->procedure[i]), r->procedure[i]);
fwrite(buff, strlen(buff), 1, fp);
}
sprintf(buff, "e 0");
fwrite(buff, strlen(buff), 1, fp);
// ...
}
void read_recipe(FILE *r, FILE *fp)
{
fread(r, sizeof(recipe), 1, fp);
// ...
while (true)
{
fread(&t, sizeof(char), 1, fp);
if (t == 'e')
{
// ...
break;
}
fread(buff, sizeof(char), 7, fp);
sscanf("%d", &len);
fread(buff, sizeof(char), len, fp);
buff[len] = 0;
ingredient = malloc(sizeof(char) * (len + 1));
strcpy(ingredient, buff);
// ...
}
// ...
while (true)
{
fread(&t, sizeof(char), 1, fp);
if (t == 'e')
{
// ...
break;
}
fread(buff, sizeof(char), 7, fp);
sscanf("%d", &len);
fread(buff, sizeof(char), len, fp);
buff[len] = 0;
procedure = malloc(sizeof(char) * (len + 1));
strcpy(procedure, buff);
// ...
}
// ...
}