在C语言中将结构体写入文件

3

这是我的代码,在其中我从“example.txt”中读取256字节,并将其存储在chunk.payload中。

我希望能够先将我的结构体写入“write.txt”,然后再将我读取的内容写入“write.txt”。我已经成功使用fwrite将chunk.payload中的所有内容写入文件,但是我无法将整个结构体写入文件。

#define MAXSIZE 256
int main(void){
    FILE *fp = fopen("C:\\Users\\alice\\Desktop\\example.txt", "r");
    FILE *wr = fopen("C:\\Users\\alice\\Desktop\\write.txt", "w+");

    struct packet{
      unsigned short block_num;
      unsigned short block_size;
      unsigned short crc;
      unsigned char *payload;
    };

    /*Create A dummy packet */
    struct packet chunk;
    chunk.block_num = 0;
    chunk.block_size = 256;
    chunk.crc = 0x101001;
    chunk.payload = malloc(MAXSIZE + 1);  // allocating memory
    chunk.payload[MAXSIZE] = '\0';

    //read first 256 lines and store into chunk.payload
    int read = fread(chunk.payload, sizeof(char), MAXSIZE, fp);  

    // Write struct to write.txt
    fwrite(&chunk, sizeof(chunk), 1, wr);

    // Write whatever has been read so far to write.txt
    fwrite(chunk.payload, sizeof(char), read, wr);

    getch();
    fclose(fp);
    fclose(wr);
    return 0;

我写的调用方式:
fwrite(&chunk, sizeof(chunk), 1, wr);

实际上,允许我编译代码,但在我读取的256字节被写入文件之前,我的文件中写入了随机符号。

正确的方法是什么?


chunk.crc = 0x101001; 这里的 short 大于 2 个字节吗? - BLUEPIXY
4个回答

1

你的第一个 fwrite 尝试将数据包结构体的二进制内容写入到 write.txt 文件中:

// Write struct to write.txt
fwrite(&chunk, sizeof(chunk), 1, wr); 

第二个:
// Write whatever has been read so far to write.txt
fwrite(chunk.payload, sizeof(char), read, wr); 

编写malloc分配的有效负载内容。我不认为你想将二进制写入文件。如果你想在有效负载之前将数据包结构值以文本形式写入文件,则需要逐个使用fprintf进行写入。

// write contents of 'chunk' to text file
fprintf( wr, "block_num= %d\n", chunk.block_num );
...
fwrite(chunk.payload, sizeof(char), read, wr);

请注意,如果读取的字节数小于MAXSIZE,则您的有效负载文本将无法正确地以零结尾。

0

负载是字符数据类型,结构体的其他成员是整数。您正在创建文本文件。因此,请将整数转换为字符,然后写入write.txt。

也可以像这样实现;

typedef struct Test
{
int a,b,c, d;
}Ref;

主函数() {

 fp=fopen("/home/test_prog/sampe.txt", "w+");
 sprintf (data, "%d %d %d %d", example.a, example.b, example.c, example.d);
 fwrite (data, sizeof(char), strlen(data) , fp  );
 fclose (fp);

}


那我需要将结构体中的每个整数类型转换为字符,然后分别使用fwrite写入吗? - user2917692
可以使用sprintf和字符串格式化函数来完成,非常简单。 - mahendiran.b

0

freadfwrite通常用于读取/写入二进制数据。如果您想要写入文本数据,通常使用fscanffgets进行输入,并使用fprintf进行输出。


0

你的结构包含指向有效载荷的指针。这些是您看到的“垃圾”字符。由于您无论如何都将有效载荷大小限制为MAXSIZE,因此可以将有效载荷设置为静态大小:

struct packet{
  unsigned short block_num;
  unsigned short block_size;
  unsigned short crc;
  unsigned char payload[MAXSIZE];
};

这样做的额外优点是不需要保存指针,使用堆等。在这种情况下,您的第一个fwrite将写入整个内容,包括有效负载,因此不需要第二个fwrite

如果您需要具有任意大小的有效负载,则可以使用这个老技巧:

struct packet{
  unsigned short block_num;
  unsigned short block_size;
  unsigned short crc;
  unsigned char payload[0];
};

/*Create A dummy packet */
struct packet *chunk;
chunk = (struct packet *)malloc(sizeof(struct packet) + packetsize + 1);
chunk->block_num = 0;
chunk->block_size = 256;
chunk->crc = 0x101001;
chunk->payload[packetsize] = '\0';

然后你需要更新你的第一个fwrite为:

// Write struct to write.txt
fwrite(chunk, sizeof(*chunk) + packetsize, 1, wr);

注意:在这种情况下,您仍然不需要第二个fwrite

另外,如果您也想保存NUL终止符,请不要忘记添加一个。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接