c - 如何将二进制文件读入缓冲区,然后在不同点设置结构指针以初始化它们?

标签 c struct

我想从二进制文件中读取一大块数据到缓冲区中,然后将指针放置在缓冲区中的不同位置以将结构存储在缓冲区中。 但是,当我尝试此方法时,我得到了错误的数据,这可能是因为我放置指针的位置。

注意:readEntry 和 writeThis 只是低级别的 read() 和 write(),内置了错误捕获。readEntry 在到达文件末尾后终止程序。

#define BUF    64

struct my_struct
{
    int num;
};

my_struct 和 BUF 的定义

int i;
char buffer[BUF];
struct my_struct *m = (struct my_struct *) malloc(sizeof(struct my_struct));

for(i=0; i<4; i++)
{   
    m->num = i;
    printf("Initializing m->num to %d\n", m->num);
    writeThis(fd, &m, sizeof(struct my_struct));
}   

lseek(fd, 0, SEEK_SET);

while(1)
{   
    printf("Read\n");
    readEntry(fd, buffer, (sizeof(struct my_struct)*4));
    m = (struct my_struct *) buffer;
    printf("num = %d\n", m->num);
    m = (struct my_struct *) buffer+(sizeof(m));
    printf("num = %d\n", m->num);
    m = (struct my_struct *) buffer+((sizeof(m)*2));
    printf("num = %d\n", m->num);
    m = (struct my_struct *) buffer+((sizeof(m)*3));
    printf("num = %d\n", m->num);
}   
return 0;

writeThis()

void writeThis(int fd, void *buffer, int writeAmt)
{
    if (write(fd, buffer, writeAmt) != writeAmt)
    {
        fprintf(stderr, "Error writing\n");
        exit(-1);
    }
}

读取条目()

void readEntry(int fd, void *buffer, int writeAmt)
{
    if (read(fd, buffer, writeAmt) != writeAmt)
    {
        printf("Finished reading\n");
        free(buffer);
        exit(0);
    }
}

我得到的 sizeof(struct my_struct) 的返回是 4

输出:

Initializing m->num to 0
Initializing m->num to 1
Initializing m->num to 2
Initializing m->num to 3
Read
num = 134524936
num = -1208081680
num = -1209552416
num = 1111804576
Read
Finished reading

十六进制转储

00000000  10 b4 04 08 10 b4 04 08  10 b4 04 08 10 b4 04 08  |................|
00000010

最佳答案

一些清理过的未经测试的代码 - 请参阅评论以修复问题。两个大的是 & 在不需要时和指针运算。

#define BUF    64

struct my_struct {
    int num;
};

int i;

// Suggest `malloc()` rather than `char buffer[BUF]`.
// The issues is _alignment_, perhaps that is new for you.
char *buffer = malloc(BUF);

// Cast not needed.  Better to use size of variable, than sizeof type.
// Think how easy this is to maintain code should `m` take on a new type.
// struct my_struct *m = (struct my_struct *) malloc(sizeof(struct my_struct));
struct my_struct *m = malloc(sizeof *m);

for(i=0; i<4; i++) {   
    m->num = i;
    printf("Initializing m->num to %d\n", m->num);
    // & not needed here.  `m` is the pointer to the place to read data
    // writeThis(fd, &m, sizeof(struct my_struct));
    // Use size of variable
    writeThis(fd, m, sizeof *m);
}   

lseek(fd, 0, SEEK_SET);

while(1)
{   
    printf("Read\n");
    // Again, use sizeof the variable, rather than size of type
    //readEntry(fd, buffer, (sizeof(struct my_struct)*4));
    readEntry(fd, buffer, sizeof *m *4);
    m = (struct my_struct *) buffer;
    printf("num = %d\n", m->num);

    // do not cast and then add to char *
    // add and then cast
    // m = (struct my_struct *) buffer+(sizeof(m));
    m = (struct my_struct *) (buffer+(sizeof(*m));
    // OR, add after the cast, but only add 1
    m = (struct my_struct *) buffer + 1;

    printf("num = %d\n", m->num);
    m = (struct my_struct *) buffer+2;
    printf("num = %d\n", m->num);
    m = (struct my_struct *) buffer+3;
    printf("num = %d\n", m->num);

    // You could have an infinite loop here, need a reason to exit
}  
free(buf);

return 0;

健壮的代码会在使用前检查 malloc() 的返回结果

关于c - 如何将二进制文件读入缓冲区,然后在不同点设置结构指针以初始化它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36412740/

相关文章:

c - 初始化结构数组

c - BSD C Bind() 到 UDP 挂起的套接字

C:通过 UDP 发送 float 导致随机符号

c++ - 用 sockaddr_in 的值填充 sockaddr_storage 结构

c - 传递结构与将变量传递给 C 中的函数

C:类型转换成不同尺寸的结构

c - 将结构数组作为结构的成员

c - 增量队列 - 嵌入式调度程序

将无符号表达式与 0 进行比较

c - 为什么 pthread_cond_signal() 没有被调用?