将文件读入struct

时间:2014-08-11 14:54:41

标签: c struct fread

我试图将文件内容读入结构体。 结构看起来像这样:

    typedef struct{
            unsigned char e_ident[EI_NIDENT] ;
            Elf32_Half e_type;
            Elf32_Half e_machine;
            Elf32_Word e_version;
            Elf32_Addr e_entry;
            Elf32_Off e_phoff;
            Elf32_Off e_shoff;
            Elf32_Word e_flags;
            Elf32_Half e_ehsize;
            Elf32_Half e_phentsize;
            Elf32_Half e_phnum;
            Elf32_Half e_shentsize;
            Elf32_Half e_shnum;
            Elf32_Half e_shstrndx;
    } Elf32_Ehdr;
extern Elf32_Ehdr elfH;

它基本上是一个ELF头文件。所以,无论如何我想将文件的内容加载到这个结构中。

该功能如下所示。

Elf32_Ehdr elfH;
int load(char* fname){
        FILE* file = fopen(fname,"r");

        if(NULL == file) return 0;

        fread(&elfH, 1, 52, file);

        fclose(file);
        return 1;
}

因为它似乎无法正常工作。 elfH的内容与预期不符。 可能是什么问题? 我应该

6 个答案:

答案 0 :(得分:0)

您必须在"b"的文件访问模式字符串("rb")中添加fopen才能进行二进制数据读取。您的硬编码精灵标题大小也可能不是一个好主意,因为您的精灵标题结构的大小可能不是62. sizeof(Elf32_Ehdr)可能是更好的方法...

答案 1 :(得分:0)

这是我用来从ELF可执行文件中读取标头的代码。

FILE* fp = fopen(fname, "rb");
if(fp == NULL)
{
    printf("failed to load\n");
    exit(1);
}

Elf32_Ehdr hdr;
if (1 != fread(&hdr, sizeof(hdr), 1, fp))
{
    printf("failed to read elf header\n");
    exit(1);
}
// If program doesn't exit, header was read and can be worked with down here.

答案 2 :(得分:0)

也许您的问题是文件中的数据不是与您的程序所期望的endianness相同。

如果比较十六进制中的预期值和实际值,您可以验证是否是这种情况 例如。如果你期望0x12345678但实际上得到0x78563412它绝对是一个字节序问题。

要获得解决方案,请参阅this问题的答案。

答案 3 :(得分:0)

C对struct的内容如何在内存中打包和对齐提供了相当有限的保证。根据编译器和平台的不同,Elf32_Ehdr结构的元素是否实际上是连续的。由于它们的大小各不相同,我对此表示怀疑(如果您打印出sizeof(Elf32_Ehdr)并将其与标题的实际磁盘大小进行比较,您可能会看到差异。)

如果您知道您正在阅读的标题长度为52个字节(正如您的代码所示),那么您需要fread那么多,然后执行类似(在大纲中)的内容

#define HDR_SIZE 52
typedef unsigned char byte;
Elf32_Ehdr hdr;

byte buf[HDR_SIZE];

fread(buf, HDR_SIZE, 1, fp);

hdr.e_version = *(Elf32_Word*)&buf[1];
...

(我猜测Elf32_Half是半字节,因此e_version在缓冲区的字节1和2(0偏移)中。)

我没有测试过,但我希望你明白这一点。

然后有一些bytesex问题让你担心......

答案 4 :(得分:0)

正如dragosht指出的那样,如果您使用某种Windows机器,则可能需要打开文件二进制文件。

您也可能遇到对齐问题。 结构可以自动插入额外的字段,以帮助维护正确的地址对齐,这是出于性能原因。

如果您正在阅读以二进制模式从相同结构编写的文件,我不希望看到该问题。

答案 5 :(得分:0)

您拥有的代码向后读取,这使if语句不正确。如果项已读取,则fread返回数字。如果向后提供size参数,则它将返回读取的字节数。因此,解决方案是给两个size参数以相反的顺序读取。

int main(int argc, char ** argv)
{
    printf("Reading %s\n", argv[1]);
    FILE* fp = fopen(argv[1], "rb");
    if(fp == NULL)
    {
            printf("file not opened\n");
            exit(-1);
    }

    Elf32_Ehdr * header = malloc(sizeof(Elf32_Ehdr));
    int value = fread(header, sizeof(Elf32_Ehdr), 1, fp);
    //int value = fread(header, 1, sizeof(Elf32_Ehdr), fp); // incorrect order
    printf("Read %d items\n", value);
    if (value != 1)
    {
            printf("failed to read elf header\n");
            exit(-1);
    }
    printf("Majick %c%c%c%c",header->e_ident[0],header->e_ident[1], header->e_ident[2], header->e_ident[3]);
    fclose(fp);
}