首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将结构对象传递给C中的函数,并使用它们对文件进行写/读?

如何将结构对象传递给C中的函数,并使用它们对文件进行写/读?
EN

Stack Overflow用户
提问于 2022-11-25 21:53:13
回答 2查看 50关注 0票数 0

我正在尝试传递一个"dino“struct对象,该对象已在C中使用格式声明。然后,我为这个名为d0的对象赋值,然后将整个对象传递给一个函数,该函数以字节格式写入文件,写入d0的所有参数。然后我尝试接受这个文件,然后读取到一个新的dino对象d1,并将每个参数的值赋给这个新的dino。当我运行它时,会出现一些错误。也就是说,我的save_dino参数是不兼容的。save_dino函数声明使用dino *d,我只是传递d0。我不明白我应该传递什么,而不是d0。第二,d是一个指针,gcc告诉我我应该用->代替。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// your code here (define the dino struct)
// use typedef struct, not just struct

typedef struct Dino {
    double lat;
    double lng;
    char *name;
} dino;

void save_dino(dino *d, char *ofn)
{
    FILE *fp = fopen(ofn, "wb");
    fwrite(&d.lat, sizeof(double), 1, fp);
    fwrite(&d.lng, sizeof(double), 1, fp);
    fwrite(d.name, strlen(d.name), 1, fp);
    fclose(fp);
}

void load_dino(dino *d, char *ifn)
{
    FILE *fp = fopen(ifn, "rb");
    fread(d.lat, sizeof(double), 1, fp);
    fread(d.lng, sizeof(double), 1, fp);
    while(!feof(fp))
    {
        fscanf(fp, "%s", d.name);
    }
}

int main(int argc, char **argv)
{
    if(argc != 2)
        return 1;
    
    char *fn = argv[1];
    
    // create a dino struct and give it the following values:
    // latitude = 51.083332
    // longitude = -1.166667
    //name = "Aves indet."
    // do NOT hardcode the string length, get it with strlen() instead
    dino d0;
    d0.lat = 51.083332;
    d0.lng = -1.166667;
    strcpy(d0.name, "Aves indet.");
    
    // call save_dino() and save d0 to the given filename (fn)
    save_dino(d0, fn);
    
    dino d1;
    
    // call load_dino() and load the file you just saved into d1 (NOT d0)
    load_dino(d1, fn);
    
    printf("d1.lat %f\n", d1.lat);
    printf("d1.lng %f\n", d1.lng);
    printf("d1.name %s\n", d1.name);
    
    return 0;
}

这是我的密码。

EN

回答 2

Stack Overflow用户

发布于 2022-11-25 23:13:07

name是一个指针。需要将内存分配给指针。

name的长度保存为文件的一部分。读取文件将需要长度来分配,然后可以读取名称。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Dino {
    double lat;
    double lng;
    char *name;
} dino;

void save_dino(dino *d, char *ofn)
{
    FILE *fp = fopen(ofn, "wb");
    fwrite(&d->lat, 1, sizeof(double), fp);
    fwrite(&d->lng, 1, sizeof(double), fp);
    size_t len = strlen ( d->name);
    fwrite(&len, 1, sizeof(size_t), fp);
    fwrite(d->name, 1, len, fp);
    fclose(fp);
}

void load_dino(dino *d, char *ifn)
{
    FILE *fp = fopen(ifn, "rb");
    fread(&d->lat, 1, sizeof(double), fp);
    fread(&d->lng, 1, sizeof(double), fp);
    size_t len = 0;
    fread(&len, 1, sizeof(size_t), fp);
    if ( NULL == ( d->name = malloc ( len + 1))) {
        fprintf ( stderr, "problem malloc\n");
        fclose ( fp);
        return;
    }
    fread(d->name, 1, len, fp);
    d->name[len] = 0;
    fclose(fp);
}

int main(int argc, char **argv)
{
    if(argc != 2)
        return 1;

    char *fn = argv[1];

    // create a dino struct and give it the following values:
    // latitude = 51.083332
    // longitude = -1.166667
    //name = "Aves indet."
    // do NOT hardcode the string length, get it with strlen() instead
    dino d0;
    d0.lat = 51.083332;
    d0.lng = -1.166667;
    d0.name = strdup ( "Aves indet.");

    // call save_dino() and save d0 to the given filename (fn)
    save_dino(&d0, fn);
    free ( d0.name);

    dino d1 = { 0.0, 0.0, NULL};

    // call load_dino() and load the file you just saved into d1 (NOT d0)
    load_dino(&d1, fn);

    printf("d1.lat %f\n", d1.lat);
    printf("d1.lng %f\n", d1.lng);
    printf("d1.name %s\n", d1.name);
    free ( d1.name);

    return 0;
}
票数 1
EN

Stack Overflow用户

发布于 2022-11-25 23:07:17

首先,我们不把结构作为对象来引用,因为在C89上,我们没有类的概念,也没有属性。

所以最好把它当作一个寄存器或者从字面上说是一个结构。

回答你的问题。最好保存整个结构,将你的dino作为一个名称类型,作为“测量”其内存大小的一种方法。

你可以试试这样的方法:

代码语言:javascript
复制
void save_dino(Dino *d, char *ofn) {
  FILE *fp; 
  if ( (fp = fopen(ofn, "wb")) == NULL ){
    return;
  }
  fwrite(d, sizeof(Dino), 1, fp);
  fclose(fp); 
}

void load_dino(Dino **d, char *ifn)
{
    FILE *fp;
    if ( (fp = fopen(ofn, "rb")) == NULL ){
       return;
    }
    fread(&(*d), sizeof(Dino), 1, fp);
    return;
}

随着时间的推移,对于您的代码有一些注意事项。在C上编码时,禁止在声明范围之外声明变量。因此,无论何时启动函数,甚至main()或任何作用域,都应该首先声明变量。另一件事是,尽量检查fopen函数的返回,像其他OS处理程序一样,这些东西很容易失败,所以让你的结更紧。特别是在打开的时候,安全和避免爆炸..。在函数内部打开时,返回int值来测试一切顺利与否,这是一个很好的实践。

如果还有任何疑问,给我留言。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74578120

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档