我有一个看起来像这样的结构:
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等级。我不知道如何像使用fscanf那样使用fread来读取单个数据。以下是我到目前为止尝试过的方法,但它不起作用:
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);
}
发布于 2017-12-17 23:02:51
我在最近的一个项目中做了a similar job。
我自己实现了一个二进制文件格式,它的结构是
MAGIC
number of records
record 1
(int) length of this record
data
record 2
(int) length of this record
data
因此,您可以将额外的4个字节(或一个整数)放入坑中,以指示要读取的内容的长度,并根据该数字进行读取。
这种实现的优点是:
,因此不需要将单个字符用作“终止符
发布于 2017-12-17 22:58:24
你需要知道文件的格式。我假设以下情况:
现在您可以读取数据了。唯一的问题是如何确定字符串的长度,因为您必须为它们分配内存。有两种方法:
buf[256]
),并逐个字符地读取,直到看到空字符(您可能希望跳过可能导致缓冲区溢出的字符,因此文件格式规范的另一部分是字符串不能超过255)。使用\0读取并终止缓冲区后,调用strlen
,然后使用malloc
或https://stackoverflow.com/questions/47856045
复制相似问题