首页 > 解决方案 > 为什么将我的 C 结构写入二进制文件会产生比结构包含更多的数据

问题描述

我正在尝试将复杂的 C 结构(包含结构的结构)写入二进制文件,但不知何故,它生成的数据多于结构包含的数据。这是我的代码:

代码清单 1

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>

typedef struct __pbi {
    char pbi_first_entry[3];
    char pbi_second_entry[8];
} PBI;

typedef struct __bpr {
    short bpr_first_entry;
    char bpr_second_entry;
    short bpr_third_entry;
    char bpr_fourth_entry;
    short bpr_fifth_entry;
    short bpr_sixth_entry;
    char bpr_seventh_entry;
    short bpr_eighth_entry;
} BPR;

typedef struct __combo {
    PBI  pbi;
    BPR  bpb;
} COMBO;

int main(int argc, char * argv[])
{
    if(argc < 2)
    {
        printf("Usage : %s device\n", argv[0]);
    }

    int dst;
    char buffer[512];
 
    int writecount;

    if((dst = open(argv[1], O_RDWR | O_CREAT)) == -1)
    {
        printf("Couldn't open file %s for writing : %s\n", argv[1], strerror(errno));
        exit(EXIT_FAILURE);
    }

    COMBO combo;

    memcpy(combo.pbi.pbi_first_entry, (char[]){0, 1, 2}, 3);
    
    printf("sizeof(pbi_first_entry) = %d\n", sizeof(combo.pbi.pbi_first_entry));
    
    memcpy(combo.pbi.pbi_second_entry, (char[]){1, 2, 3, 4, 5, 6, 7, 8}, 8);

    printf("sizeof(pbi_second_entry) = %d\n", sizeof(combo.pbi.pbi_second_entry));

    combo.bpb.bpr_first_entry = 0x0201;

    printf("sizeof(bpr_first_entry) = %d\n", sizeof(combo.bpb.bpr_first_entry));
    
    combo.bpb.bpr_second_entry = 1;

    printf("sizeof(bpr_second_entry) = %d\n", sizeof(combo.bpb.bpr_second_entry));

    combo.bpb.bpr_third_entry = 0x0201;

    printf("sizeof(bpr_third_entry) = %d\n", sizeof(combo.bpb.bpr_third_entry));
    
    combo.bpb.bpr_fourth_entry = 1;

    printf("sizeof(bpr_fourth_entry) = %d\n", sizeof(combo.bpb.bpr_fourth_entry));

    combo.bpb.bpr_fifth_entry = 0x0201;

    printf("sizeof(bpr_fifth_entry) = %d\n", sizeof(combo.bpb.bpr_fifth_entry));
    
    combo.bpb.bpr_sixth_entry = 0x0B0A;

    printf("sizeof(bpr_sixth_entry) = %d\n", sizeof(combo.bpb.bpr_sixth_entry));
    
    combo.bpb.bpr_seventh_entry = 1;

    printf("sizeof(bpr_seventh_entry) = %d\n", sizeof(combo.bpb.bpr_seventh_entry));

    combo.bpb.bpr_eighth_entry = 0x0201;

    printf("sizeof(bpr_eighth_entry) = %d\n", sizeof(combo.bpb.bpr_eighth_entry));
    
    printf("sizeof(combo) = %d\n", sizeof(combo));

    if((writecount = write(dst, &combo, sizeof(combo))) == -1)
    {
        printf("Failed to write the combo file : %s\n", strerror(errno));
        exit(-5);   
    }

    printf("Successfully wrote %d byte(s)!\n", writecount);

    close(dst);

    return(EXIT_SUCCESS);
}

当我编译并运行代码时,我得到以下输出:

输出清单 1

sizeof(pbi_first_entry) = 3
sizeof(pbi_second_entry) = 8
sizeof(bpr_first_entry) = 2
sizeof(bpr_second_entry) = 1
sizeof(bpr_third_entry) = 2
sizeof(bpr_fourth_entry) = 1
sizeof(bpr_fifth_entry) = 2
sizeof(bpr_sixth_entry) = 2
sizeof(bpr_seventh_entry) = 1
sizeof(bpr_eighth_entry) = 2
sizeof(combo) = 28
Successfully wrote 28 byte(s)!

如果为每个条目添加 sizeof() 返回的值,它们将加起来为 24,但由于某种原因 sizeof(combo) 等于 28。combo 是整个结构。也因为 combo 在某种程度上等于 28 ;28 个字节被写入文件。

这是二进制文件的十六进制内容:

十六进制列表 1

00 01 02 01 02 03 04 05 06 07 08 28 01 02 01 FF
01 02 01 28 01 02 0A 0B 01 B1 01 02

如你看到的 ; 直到第 11 个字节一切都很好,然后有一个字节的值等于0x28 ,然后一切都恢复正常,直到我们遇到另一个char,然后是 ashort并且它再次发生:我们从0x0201short)开始,然后是1char) 然后出现一个神秘的字节,其值为0xFF。每次遇到 achar后跟 a时都会发生这种情况short0x280xB1作为神秘值)。

标签: cstruct

解决方案


推荐阅读