简体   繁体   English

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

[英]Wrong Output while using fwrite() on C

I recently started doing a small project in C to learn how to properly handle working with output and input for a file.我最近开始用 C 做一个小项目来学习如何正确处理文件的输出和输入。

The situation is as follows:情况如下:
When I use a char array all works fine, but when I pass a struct as a parameter to fwrite() the output goes crazy.当我使用 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;

That's a really short project for learning, so I skipped some stuff like printf for name surname etc etc.这是一个非常短的学习项目,所以我跳过了一些诸如 printf 之类的名字姓氏等内容。
This is the output I get when I open the file这是我打开文件时得到的输出

GIulio ÿÿÿÿSavoca E' un ottimo student GIulio ÿÿÿÿSavoca E' un ottimo 学生

First there's nothing "crazy" about that output.首先,该输出并没有什么“疯狂”之处。 Don't expect any "magic" happening, writing a struct to a file just does write exactly how the struct is stored in RAM, byte by byte .不要指望发生任何“魔法”,将结构写入文件只是准确地写入结构在 RAM 中的存储方式,逐字节

Second, that's almost never what you want, because the layout in memory for a struct will differ from machine to machine, sometimes even from compiler to compiler.其次,这几乎永远不是您想要的,因为struct在内存中的布局会因机器而异,有时甚至因编译器而异。 For writing structs to a file and reading them back reliably, you have to do some sort of (de-)serialization using only textual representations of all individual fields.为了将结构写入文件并可靠地读回它们,您必须仅使用所有单个字段的文本表示进行某种(反)序列化。


Very basic example of (de-)serializing a struct : (反)序列化struct非常基本的示例:

This example is really minimal and stores a struct in a file line-by-line, assuming the struct and all pointer fields are allocated dynamically.这个例子实际上是最小的,并且存储struct在文件中的行由行,假设结构和所有指针字段是动态分配的。 I didn't test this code, it might have a bug, just to show a simple idea.我没有测试这段代码,它可能有一个错误,只是为了展示一个简单的想法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM