读取二进制文件时如何分别对每个结构字段使用 fread()?

How to use fread() for each struct field separately when reading binary file?

在我的struct中我有字段

struct records {
    short link; 
    double gate; 
    unsigned char bar;
    int rest; 
    char rink; 
};

在我的 main()

int main(int argc, char* argv[]){
    struct records rec;

    if(argc<2){//no paramaters
        //return error
    }

    FILE *fp=fopen(argv[1], "rb");

    if(fp==NULL){//no file
         //return error
    }

    //use fread() for each field in struct separately.   

    fclose(fp);
    return 0;
}

如何调用 fread() 以便它分别读取每个 struct 字段,然后将它们打印出来?我知道(每个类似的在线问题和 tut)显示通过提供整个 struct 来调用 fread(),但我不想这样做,例如。 fread(&rec, sizeof(rec), 1, fp)。我想用自己的 fread() 调用分别读取每个字段。感谢任何帮助,谢谢。

fread 需要两个重要参数:指针和长度。

您可以轻松获得两者:

struct records {
    short link; 
    double gate; 
    unsigned char bar;
    int rest; 
    char rink; 
};

int main(int argc, char* argv[]){
    struct records rec;

    // ...

    FILE *fp=fopen(argv[1], "rb");

    // ...

    //use fread() for each field in struct separately.   

    while (!feof(fp))
    {
        if (fread(&rec.link, sizeof(rec.link), 1, fp) != 1
           || fread(&rec.gate, sizeof(rec.gate), 1, fp) != 1
           || // etc...
           )
        {
            // error !
        }
        // print the contents of rec, for example...
    }
    // ...
}

我来晚了,但这可能有用。

您可以在 offsetof() 函数的帮助下完成此操作。

这里涉及填充字节。

sizeof(struct records) 在我的机器中是 32 字节(但不同机器可能不同)。

然而 struct record 变量的所有成员的组合大小仅为 sizeof(short)+sizeof(double)+sizeof(unsigned char)+sizeof(int)+sizeof(char) 在我的机器上应该是 16 字节(假设 short, double, unsigned char, int & char 占用 2 , 8, 1, 4 & 1 字节)。

这是因为所谓的填充字节。您可以阅读此 here。这样做是为了让处理器更轻松。

所以根据这些尺寸,

一个struct record就像

----------------------------------------------------------------
|    link(2)     |                 6 bytes                     |
----------------------------------------------------------------
|                         gate (8)                             |
----------------------------------------------------------------
|  bar(1)  |      3 bytes      |            rest(4)            |
----------------------------------------------------------------
|  rink(1) |                7 bytes                            |
----------------------------------------------------------------

首先找到struct的每个成员开始的点

printf("link: %d\n", offsetof(struct records, link));
printf("gate: %d\n", offsetof(struct records, gate));
printf("bar: %d\n", offsetof(struct records, bar));
printf("rest: %d\n", offsetof(struct records, rest));
printf("rink: %d\n", offsetof(struct records, rink));

这会打印

link: 0
gate: 8
bar: 16
rest: 20
rink: 24

您可以使用此方法来查找结构成员在您的机器中是如何打包的。

您现在需要做的是在忽略填充字节的情况下读取所需的数据。

让我们创建一个结构变量a

fread(&a.link, sizeof(a.link), 1, fp);
fseek(fp, 6, 1); //move the file pointer by 6 bytes from current position to avoid the padding bytes

fread(&a.gate, sizeof(a.gate), 1, fp);
fread(&a.bar, sizeof(a.bar), 1, fp);
fseek(fp, 3, 1); //move the file pointer to avoid the 3 bytes

fread(&a.rest, sizeof(a.rest), 1, fp);
fread(&a.rink, sizeof(a.rink), 1, fp);

现在您可以使用 a 中的值。



当你问上一个问题时,我不知道该怎么做。但是我做了一些阅读并找到了一种方法。由于您 post 提出了一个单独的问题,我认为最好在此处 post 回答。