我如何阅读二进制文件并将其值分配给结构?每个结构及其内容都将写入csv文件。
我有这个data file,它是struct product
条目的列表。
这是h文件中的Product
结构:
struct product {
char code[15];
char name[50];
short int quantity;
double price;
}
typedef struct product *Product;
以下是我尝试将每行读入Product结构并将其写入csv文件的方法:
File *fp;
File *outFile;
fp = fopen("products.dat", "rb");
outFile = fopen("allproducts.csv", "w");
Product p;
while (fread(p, sizeof(Product), 1, fp) == 1) {
fwrite(p->code, sizeof(p->code), 1, outFile);
}
我不认为我正确地读取文件,因为当我尝试写入文件时,我得到的只是csv文件中一个框中的问号。
答案 0 :(得分:1)
如果数据文件的编写者没有注意它所写的struct
的大小,那么读者就很难理解它。我玩了一下,发现需要进行一些小调整才能在我的机器和操作系统上获得正确的结果。
#include <stdio.h>
#include <stdlib.h>
#define ADJUSTMENT 4
struct product {
char code[15];
char name[50];
short int quantity;
double price;
};
int main(void)
{
FILE *fp;
//FILE *outFile;
struct product p;
fp = fopen("products.dat", "rb");
if (fp == NULL) {
fprintf(stderr, "fopen failed\n");
exit(EXIT_FAILURE);
}
//outFile = fopen("allproducts.csv", "w");
while (fread(&p, sizeof(p) - ADJUSTMENT, 1, fp) == 1) {
printf("CODE: %s\n", p.code);
}
exit(EXIT_SUCCESS);
}
这是一个众所周知的问题,如此简单的尝试编写二进制数据,它只是不便携,我很确定我的调整值不适合你。您需要找到一种方法使其可移植。
答案 1 :(得分:0)
我认为您需要修改以下代码。
您的原始代码:
File *fp;
File *outFile;
fp = fopen("products.dat", "rb");
outFile = fopen("allproducts.csv", "w");
Product p;
while (fread(p, sizeof(Product), 1, fp) == 1) {
fwrite(p->code, sizeof(p->code), 1, outFile);
}
修改后的代码:
File *fp;
File *outFile;
fp = fopen("products.dat", "rb");
outFile = fopen("allproducts.csv", "w");
Product p = malloc(sizeof(struct product));
while (fread(p, sizeof(struct product), 1, fp) == 1) {
fwrite(p->code, sizeof(p->code), 1, outFile);
}
问题是:
p
是一个指向struct的指针,因为它是Product
类型,它是指向struct的指针,你需要先为它分配内存才能使用它fread
中,您传递的sizeof(Product)
基本上会传递指针的大小,而您想要读取结构产品的大小。我没有纠正的其他问题是检查fopen,malloc等的返回值,我把它留给你。 :)
答案 2 :(得分:0)
隐藏typedef背后的指针容易出错,导致代码混乱。
p
被定义为指向struct product
的指针,但未初始化:将其值传递给fread
,因为目标调用未定义的行为。
sizeof(Product)
是指针的大小,而不是结构的大小。
不要将Product
定义为指针,如果可以,请将其设为结构的typedef,如果不能,则不要使用typedef:
struct product {
char code[15];
char name[50];
short int quantity;
double price;
};
typedef struct product Product;
调整代码并将字符串写入csv
文件,而不是完整的字符数组:
File *fp;
File *outFile;
fp = fopen("products.dat", "rb");
outFile = fopen("allproducts.csv", "w");
struct product prod;
while (fread(&prod, sizeof(prod), 1, fp) == 1) {
fprintf(outFile, "%s\n", prod.code);
}
请注意,如果产品代码包含嵌入的空格,
,"
或换行符,则此选项不正确。