我最近开始用C做一个小项目,学习如何正确处理文件的输出和输入。
情况如下:
当我使用char数组时,一切正常,但是当我将一个struct作为参数传递给fwrite()时,输出会变得疯狂。
FILE *fp;
Acazzo a;
fp = fopen("Inserimento.dat","w");
gets(a.nome);
fflush(stdin);
gets(a.cognome);
fflush(stdin);
gets(a.note);
fflush(stdin);
fwrite(&a,sizeof(a),1,fp);
fclose(fp);
return 0;
这是一个非常简短的学习项目,所以我跳过一些像printf这样的东西,如姓氏等等 这是我打开文件时得到的输出
GIulioÿÿÿÿSavocaE'unottimo student
答案 0 :(得分:2)
首先,对于那个输出没有任何“疯狂”。不要指望发生任何“魔术”,将结构写入文件只是确切地写出结构如何存储在RAM中,逐字节。
其次,这几乎不是你想要的,因为struct
的内存布局因机器而异,有时甚至从编译器到编译器。为了将结构写入文件并可靠地读取它们, 只使用所有单个字段的文本表示来进行某种(反)序列化。
(取消)序列化struct
的基本示例:
此示例实际上是最小的,并且逐行地将struct
存储在文件中,假设结构和所有指针字段是动态分配的。我没有测试这段代码,它可能有一个bug,只是为了表明一个简单的想法。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct data
{
int id;
char *name;
char *value;
} data;
static char *copyInput(char *buf)
{
char *copy;
size_t endpos = strlen(buf) - 1;
while (buf[endpos] == '\r' || buf[endpos] == '\n')
{
buf[endpos] = 0;
--endpos;
}
copy = malloc(strlen(buf) + 1);
strcpy(copy, buf);
return copy;
}
data *data_deserialize(FILE *fp)
{
char buf[256];
data *d = calloc(1, sizeof(*d));
if (!d) return 0;
if (!fgets(buf, 256, fp)) goto err;
d->id = atoi(buf);
if (!fgets(buf, 256, fp)) goto err;
d->name = copyInput(buf);
if (!fgets(buf, 256, fp)) goto err;
d->value = copyInput(buf);
return d;
err:
free(d->name);
free(d->value);
free(d);
return 0;
}
int data_serialize(FILE *fp, const data *d)
{
int rc;
rc = fprintf(fp, "%d\n", d->id);
if (rc < 0) return rc;
rc = fprintf(fp, "%s\n", d->name);
if (rc < 0) return rc;
rc = fprintf(fp, "%s\n", d->value);
return rc;
}