在C中打开和读取文件的问题

时间:2014-08-05 10:06:57

标签: c

我有一些程序应该在调用程序后立即从命令行读取文件名。然后,它读入文件中的所有数据,包括标题数据等,它们被定义为以下结构的一部分。

当我从另一个来源读取标题信息时,它告诉我我有29个节标题,但是当我使用我自己的函数时(下面)它说我有0.我不知道我是否打开这个档案不正确。这里出了什么问题?

这就是我打开文件的方式:

int main(int argc, char *argv[])
{ 
    // open the file.
    FILE *fp = fopen(argv[1], "r");

    // read in the data.
    void *data = get_elf_data(fp);
}

这是标题结构:

typedef struct {
    unsigned char  identity[16];        // ELF specification information
    unsigned short nsectionheaders; // count of section headers in table
} FileHeader;

这是应该在数据中读取的函数:

static void *get_elf_data(FILE *fp)
{
    char ELF_IDENTITY[] = { 0x7f, 'E', 'L', 'F', ELFCLASS32, ELFDATA2LSB, EV_CURRENT};
    FileHeader hdr;
    int nread = fread(hdr.identity, 1, sizeof(ELF_IDENTITY), fp);  // read first bytes, verify proper ELF header
    if (nread < sizeof(ELF_IDENTITY) || memcmp(hdr.identity, ELF_IDENTITY, sizeof(ELF_IDENTITY)) != 0)
        return NULL; // reject if file doesn't have correct 32-bit Elf header

    fseek(fp, 0, SEEK_END);
    int size = ftell(fp);       // get number of bytes in entire file
    rewind(fp);
    void *data = malloc(size);
    if (!data)
        return NULL;
    nread = fread(data, 1, size, fp);  // read entire file into memory
    if (nread != size) return NULL;
    printf("The number of section headers %d\n", hdr.nsectionheaders);
    return data;

}

该函数也没有返回NULL。

2 个答案:

答案 0 :(得分:0)

您只能将ELF_IDENTITY读入hdr

    int nread = fread(hdr.identity, 1, sizeof(ELF_IDENTITY), fp);  // read first bytes, verify proper ELF header

在可靠地使用nsectionheaders字段之前,您需要将此标题的其余部分读入此结构。

此修复程序应该足够简单:将sizeof(ELF_IDENTITY)上方更改为sizeof(hdr)

答案 1 :(得分:0)

我认为,由于您没有要求提供紧凑的结构,因此C编译器未对标题中的字段进行错位。

也许你最好每个字符读取它们的字符,以在体系结构独立模式下构建标题字段。通常情况下,如果你有一个四字节整数并且你声明了一个char,然后是一个短路,那么你将得到短填充到16位边界,在你的结构中留下一个洞(一个字节的一个洞)。

您可以使用C编译器在某些压缩结构中正确对齐字段,但执行此操作的详细信息取决于编译器。

在gcc中,它可以用以下内容完成:(借用手册)

      struct my_unpacked_struct
       {
          char c;
          int i;
       };

      struct __attribute__ ((__packed__)) my_packed_struct
        {
           char c;
           int  i;
           struct my_unpacked_struct s;
        };

但您的编译器可以采用另一种方式。

注意:字段将采用这种方式(在x86 intel上):


    offset  field
    ======  =====
    0       [my_packed_struct.c]
    1       [my_packed_struct.i.lsb]
    5       [my_packed_struct.s.c]
    9       [my_packed_struct.s.i.lsb]
    13      [end]

我不得不说这是一个复杂的例子,因为你在一个打包的中间放置了一个未对齐的解包结构。

BR