我有一个名为 product 的结构,我试图从二进制文件中读取以填充此函数:
void reading(FILE *fp){
Product *obuff = malloc(sizeof(Product));
fread(obuff->code, sizeof(obuff->code), 1, fp);
fread(obuff->name, sizeof(obuff->name), 1, fp);
fread(obuff->quantity, sizeof(obuff->quantity), 1, fp);
fread(obuff->price, sizeof(obuff->price), 1, fp);
printf("%s %s %d %.2f\n", obuff.code, obuff.name, obuff.quantity, obuff.price);
}
当我尝试编译时,我得到错误,说我因为错误的数据类型而无法传递参数。有没有办法从二进制文件读取结构,或者我在这里做错了什么?
结构:
#pragma pack(2)
struct product {
char code[15];
char name[50];
short int quantity;
double price;
};
#pragma pack()
typedef struct product Product;
答案 0 :(得分:2)
您必须传递指针以使fread()
读取数据。
void reading(FILE *fp){
Product *obuff = malloc(sizeof(Product));
fread(&obuff->code, sizeof(obuff->code), 1, fp);
fread(&obuff->name, sizeof(obuff->name), 1, fp);
fread(&obuff->quantity, sizeof(obuff->quantity), 1, fp);
fread(&obuff->price, sizeof(obuff->price), 1, fp);
printf("%s %s %d %.2f\n", obuff->code, obuff->name, obuff->quantity, obuff->price);
free(obuff); /* free whatever you allocated after finished using them */
}
答案 1 :(得分:1)
此代码存在一些问题。其中一些会阻止编译,而其他一些可能会导致不稳定的行为。由于不稳定的行为是您可能不会注意到的,我将首先介绍它。
在尝试使用之前,您应该始终检查malloc
的返回值。例如:
Product *obuff = malloc(sizeof *obuff);
if (obuff == NULL) {
/* obuff can't be used because allocation failed */
return;
}
在相关的说明中,正如MikeCAT建议的那样,当您完成任何事情free
时,可以使用malloc
来避免内存泄漏' d,realloc
' d或calloc
' d ...
在其他相关说明中,除非{{1}的返回值,否则您也不应使用值obuff->code
,name
,quality
和price
表示成功。
fread
这会编译,但你不需要&符号(fread(&obuff->code, sizeof(obuff->code), 1, fp);
fread(&obuff->name, sizeof(obuff->name), 1, fp);
),实际上不应该在这里使用它们。表达式&
和obuff->code
都指向同一位置(因为&obuff->code
是一个数组),但它们指向的对象类型不同; obuff->code
指向数组的第一个字节,而obuff->code
指向整个数组。
&obuff->code
这将编译,并澄清你做需要这里的&符号,但是说fread(&obuff->quantity, sizeof(obuff->quantity), 1, fp);
fread(&obuff->price, sizeof(obuff->price), 1, fp);
和short int
可能在不同的系统上有不同的表示。 您需要通过序列化这些字段在文件中形成一致的表示形式。序列化是一个冗长的主题,更适合软件设计手册中的一章,因此为了简洁起见,我将继续前进,除非在此提出有关此主题的更多具体问题。
double
这是不可移植的,在您提供的代码中并不需要它。
#pragma pack(2)
预期printf("%s %s %d %.2f\n", obuff.code, obuff.name, obuff.quantity, obuff.price);
对应于指向字符串的指针; 字符串是以第一个%s
字符结尾的字符序列。但是,您的代码并未明确指定任何'\0'
字符,因此我们无法保证'\0'
和obuff.code
是字符串。如果他们不是,则行为未定义(或不稳定,正如我想描述的那样)。也许您打算分别使用obuff.name
和%15s
来表示他们可能是字符串,但如果他们不是,那就是最大长度?< / p>
这也是编译错误的来源。请注意您之前引用的代码片段%50s
,obuff->code
等如何在此片段中引用obuff->name
等> STRONG>? obuff.code
运算符访问结构的字段,而.
运算符访问指向结构的字段...也许您打算在这里使用->
运算符? / p>
答案 2 :(得分:0)
由http://www.tutorialspoint.com/c_standard_library/c_function_fread.htm引用,你必须将指针传递给fread:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
你的第一个fread参数不是指针;
fread(obuff->code ...
答案 3 :(得分:0)
请注意fread()的定义,第一个argumnet需要是一个指针。另一个垃圾错误是我们需要使用“ - &gt;”获取printf()函数中的元素。
以下是我的修改:
void reading(FILE *fp){
Product *obuff = malloc(sizeof(Product));
fread(obuff->code, sizeof(obuff->code), 1, fp);
fread(obuff->name, sizeof(obuff->name), 1, fp);
fread(&obuff->quantity, sizeof(obuff->quantity), 1, fp);
fread(&obuff->price, sizeof(obuff->price), 1, fp);
printf("%s %s %d %.2f\n", obuff->code, obuff->name, obuff->quantity, obuff->price);
}