c - 在 C 上使用 fwrite() 时输出错误

标签 c file struct fwrite

我最近开始用 C 语言做一个小项目,以学习如何正确处理文件的输出和输入。

情况如下:
当我使用 char 数组时一切正常,但是当我将结构作为参数传递给 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 ÿÿÿÿSavoca E' un ottimo student

最佳答案

首先,该输出没有什么“疯狂”之处。不要指望会发生任何“魔法”,将结构写入文件只是准确地写入结构在 RAM 中的存储方式,逐字节

其次,这几乎不是您想要的,因为 struct 的内存布局因机器而异,有时甚至因编译器而异。为了将结构写入文件并可靠地读回它们,您必须仅使用所有单独字段的文本表示进行某种(反)序列化。

<小时/>

(反)序列化结构的非常基本的示例:

这个示例确实很小,它在文件中逐行存储一个struct,假设该结构和所有指针字段都是动态分配的。我没有测试这段代码,它可能有一个错误,只是为了展示一个简单的想法。

#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;
}

关于c - 在 C 上使用 fwrite() 时输出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33064496/

相关文章:

c - 使用空格字符进行数组操作;迭代

C struct typedef 和声明导致指针错误

c - 取消引用结构内的数据 ** 在结构内 *

c - 使用C语言命名linux机器的服务器IP

c - 将 C 字符串数组传递给 Fortran (iso_c_binding)

c - 为什么 free() 并没有真正释放内存?

python - 管理不同对象的文件打开和关闭职责

java - 将 String 数组转换为 int 值并将其存储在 int 数组中

每次循环后 Python 保存到磁盘的速度变慢

c# - 访问列表中的对象 C#