我有一个看起来像这样的结构:
typedef struct Student { //dynamically allocated structure
char *first_name;
char *last_name;
float grade;
}Student;
我想要做的是从二进制文件中读取数据并为first_name和last_name字段动态分配内存。从普通的.txt文件读取时,我成功完成了这项任务。这是代码:
void Read_From_File(const char *file_name, Student *p_destination, const int number_of_students)
{
FILE *p_file = fopen(file_name, "r");
if (!p_file)
{
perror("Error opening the file. \n");
exit(EXIT_FAILURE);
}
int index = 0;
while (index < number_of_students)
{
unsigned char buffer[256];
fscanf (p_file, "%s", buffer);
p_destination[index].last_name = (char*)malloc(strlen(buffer) + 1);
strcpy(p_destination[index].last_name, buffer);
fscanf(p_file, "%s", buffer);
p_destination[index].first_name = (char*)malloc(strlen(buffer) + 1);
strcpy(p_destination[index].first_name, buffer);
fscanf(p_file, "%f", &p_destination[index].grade);
index++;
}
fclose(p_file);
}
这很简单,因为fscanf可以单独读取数据并具有类型说明符,如下所示:%s 姓氏/ %s 名字/ %f 等级。我不知道如何使用fread读取单个数据,就像我使用fscanf 一样。这是我到目前为止尝试过的,但它不起作用:
int number_of_students = 0;
unsigned char buffer[256];
char file_name[10];
FILE *p_file = NULL;
Student *p_students = NULL;
printf("Enter file name. \n");
scanf("%s", file_name);
p_file = fopen(file_name, "rb");
fread(&number_of_students, sizeof(number_of_students), 1, p_file);
p_students = (Student *)malloc(number_of_students * sizeof(Student));
if (!p_students)
{
perror("Could not allocate memory. \n");
exit(EXIT_FAILURE);
}
for (int index = 0; index < number_of_students; ++index)
{
fread(buffer, sizeof(char), 1, p_file);
p_students[index].last_name = (char *)malloc(strlen(buffer) + 1);
if (!p_students[index].last_name)
{
printf("Could not allocate memory. \n");
exit(EXIT_FAILURE);
}
strcpy(p_students[index].last_name, buffer);
fread(buffer, sizeof(char), 1, p_file);
p_students[index].first_name = (char *)malloc(strlen(buffer) + 1);
if (!p_students[index].first_name)
{
printf("Could not allocate memory. \n");
exit(EXIT_FAILURE);
}
strcpy(p_students[index].first_name, buffer);
fread(&p_students[index].grade, sizeof(float), 1, p_file);
}
Print_Students(p_students, number_of_students);
此外,Print_Students函数如下所示:
void Print_Students(Student *p_students, int number_of_students)
{
printf("================================================================================================\n");
for (unsigned int index = 0; index < number_of_students; ++index)
{
printf("\t\t===================== Student %d =====================\n\n", index);
printf("Last name: %s\n", p_students[index].last_name);
printf("First name: %s\n", p_students[index].first_name);
printf("Grade: %.2f\n", p_students[index].grade);
}
printf("\n");
}
input.txt 文件如下所示:
19
Terresa Minaya 9.50
Otto Pleiman 7
Illa Holzman 5.25
Alona Greeson 3.40
Natalya Vickrey 10
Catrina Cho 9.34
Loida Dinapoli 9.43
Neely Mcelligott 8.30
Salome Urban 8.75
Rosetta Dagenhart 9.10
Diane Cooksey 10
Novella Longmire 3
Gilberte Manganaro 4
Joye Humbert 5
Justa Larock 6
Delana Bufkin 7
Genaro Kenison 8.98
Refugio Arena 4.56
Iona Nida 7.65
我将这个文件中的数据加载到我的学生向量中,然后我根据我的向量中的数据编写了input.bin文件。我使用以下代码写入二进制文件:
void Write_To_Binary(const char *file_name, Student *p_source, const int number_of_students)
{
size_t successfully_written = 0;
FILE *p_file = fopen(file_name, "wb");
if (!p_file)
{
perror("Error opening the file. \n");
exit(EXIT_FAILURE);
}
successfully_written = fwrite(&number_of_students, sizeof(number_of_students), 1, p_file);
if (successfully_written != 1)
{
perror("Error writing to the file. \n");
exit(EXIT_FAILURE);
}
successfully_written = fwrite(p_source, sizeof(Student), number_of_students, p_file);
if (successfully_written != number_of_students)
{
perror("Error writing all the student data. \n");
exit(EXIT_FAILURE);
}
fclose(p_file);
}
更新:我遵循了 iBug 的解决方案并且它有效。我更改了数据字段,如下所示: sizeof(last_name) last_name sizeof(first_name) first_name Grade。
我将在这里发布我用来写入 bin 文件并从中读取的函数。
这是函数Write_To_Binary
void Write_To_Binary(const char *file_name, Student *p_source, const unsigned int number_of_students)
{
FILE *p_file = fopen(file_name, "wb");
if (!p_file)
{
perror("Error opening the file. \n");
exit(EXIT_FAILURE);
}
size_t successfully_written = 0;
successfully_written = fwrite(&number_of_students, sizeof(number_of_students), 1, p_file);
if (successfully_written != 1)
{
printf("Error writing to the file. \n");
exit(EXIT_FAILURE);
}
unsigned int width = 0, width1 = 0;
for (unsigned int index = 0; index < number_of_students; ++index)
{
width = strlen(p_source[index].last_name) + 1;
successfully_written = fwrite(&width, sizeof(width), 1, p_file);
printf("Name: %s Width: %d \n", p_source[index].last_name, width);
if (successfully_written != 1)
{
printf("Error writing to the file. \n");
exit(EXIT_FAILURE);
}
successfully_written = fwrite(p_source[index].last_name, width, 1, p_file);
if (successfully_written != 1)
{
printf("Error writing to the file. \n");
exit(EXIT_FAILURE);
}
width = strlen(p_source[index].first_name) + 1;
successfully_written = fwrite(&width, sizeof(width), 1, p_file);
if (successfully_written != 1)
{
printf("Error writing to the file. \n");
exit(EXIT_FAILURE);
}
successfully_written = fwrite(p_source[index].first_name, width, 1, p_file);
if (successfully_written != 1)
{
printf("Error writing to the file. \n");
exit(EXIT_FAILURE);
}
successfully_written = fwrite(&p_source[index].grade, sizeof(float), 1, p_file);
if (successfully_written != 1)
{
printf("Error writing to the file. \n");
exit(EXIT_FAILURE);
}
}
fclose(p_file);
}
这是函数Read_From_Binary
void Read_From_Binary(const char *file_name, Student *p_destination)
{
FILE *p_file = fopen(file_name, "rb");
if (!p_file)
{
perror("Error opening file. \n");
exit(EXIT_FAILURE);
}
unsigned int number_of_students = 0;
size_t successfully_read;
successfully_read = fread(&number_of_students, sizeof(number_of_students), 1, p_file);
if (successfully_read != 1)
{
printf("Error reading the number of students. \n");
exit(EXIT_FAILURE);
}
unsigned int width = 0;
for (unsigned int index = 0; index < number_of_students; ++index)
{
successfully_read = fread(&width, sizeof(width), 1, p_file);
if (successfully_read != 1)
{
printf("Error reading from the file. \n");
exit(EXIT_FAILURE);
}
p_destination[index].last_name = (char*)malloc(width);
if (!p_destination[index].last_name)
{
printf("Could not allocate memory. \n");
exit(EXIT_FAILURE);
}
successfully_read = fread(p_destination[index].last_name, width, 1, p_file);
if (successfully_read != 1)
{
printf("Error reading from the file. \n");
exit(EXIT_FAILURE);
}
successfully_read = fread(&width, sizeof(width), 1, p_file);
if (successfully_read != 1)
{
printf("Error reading from the file. \n");
exit(EXIT_FAILURE);
}
p_destination[index].first_name = (char*)malloc(width);
if (!p_destination[index].first_name)
{
printf("Could not allocate memory. \n");
exit(EXIT_FAILURE);
}
successfully_read = fread(p_destination[index].first_name, width, 1, p_file);
if (successfully_read != 1)
{
printf("Error reading from the file. \n");
exit(EXIT_FAILURE);
}
successfully_read = fread(&p_destination[index].grade, sizeof(float), 1, p_file);
if (successfully_read != 1)
{
printf("Error reading from the file. \n");
exit(EXIT_FAILURE);
}
}
fclose(p_file);
}
我在最近的一个项目中做了类似的工作。
我自己实现了一个二进制文件格式,它的结构是
MAGIC
number of records
record 1
(int) length of this record
data
record 2
(int) length of this record
data
所以你可以多留一个 4 个字节(或一个整数)来表示要读取的内容的长度,并根据该数字进行读取。
这种实现的优点是:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句