如何从二进制文件中正确读取?
How do I read properly from a binary file?
我已经将我的代码缩减到最少,我认为这就是我解决问题所需的一切。
我希望用户能够阅读这个结构:
typedef struct {
char movieTitle[30];
unsigned int yearPublished;
char director[50];
char genre[50];
float profit;
} movie_t;
来自一个已经有 4 部电影的二进制文件,但也应该能够存储最多 100 部电影结构,如下定义:
//global var.
// ================================================================
#define MAX_STORAGE 100
movie_t movieData[MAX_STORAGE];
movie_t movieRecord;
unsigned int movieCount = 0;
使用我已经在下面编写的代码,我无法以某种方式从文件中读取所有电影,因为我的“计数检查器”每次都告诉我只读取了一部电影。在我的“readFile”函数下方的控制台输出代码中也只显示了一部电影。
// main functions --- read from file
// ================================================================
int
readFile(const char* fileName)
{
//open file
FILE* read = fopen(fileName, "rb");
if (!read)
{
printf("ERROR: Could not open the file!\n");
return -1;
}
else
{
printf("%s were opened successfully.\n\n", fileName);
}
//read from file
int count = 0;
while (!feof(read))
{
size_t count = fread(&movieRecord, sizeof(movieRecord), 1, read);
if (count == 0)
{
printf("ERROR: Read process was unsuccessful or incomplete!\n");
}
if (count == 1)
{
printf("Successfully read %i movie.\n", count);
}
else
{
printf("Successfully read %i movies.\n", count);
}
return count;
}
fclose(read);
return 0;
}
这是应该显示文件中所有电影的控制台输出。此外,它们应该显示 1 - 100 之间的数字 (Num.)。
// main functions --- console Output
// ================================================================
void
consoleOutput(movie_t movieData2, unsigned index)
{
printf("MOVIE DATA Num. %u\n\n", index);
printf("Movie title : %s\n", movieData2.movieTitle);
printf("Publishing year : %u\n", movieData2.yearPublished);
printf("Director : %s\n", movieData2.director);
printf("Genre : %s\n", movieData2.genre);
printf("Profit : %.2f\n", movieData2.profit);
}
这是我的主要功能的样子,如果你想看的话:
// MAIN
// ================================================================
int main(void)
{
// defaultname for file
char fileName[50] = "movies.dat";
// variable for loop
int stopLoop = 0;
// loop
do {
// Output menu
printf("\nMENU:\n");
printf("(a) Show all movies\n");
printf("(o) Read moviefile\n");
printf("(q) Exit programm\n");
printf("\nYour choice: ");
// User input
char ch = _getch();
printf("%c\n\n", ch);
// Switch case for user input
switch (ch)
{
case 'q': // Exit programm
stopLoop = 1;
break;
case 'a': // Show all movies
consoleOutput(movieRecord, movieCount = readFile(fileName));
break;
case 'o': // Read moviefile
readFile(fileName);
break;
default:
printf("==> Invalid input!\n");
}
} while (!stopLoop);
return 0;
}
旁注:因为用户能够输入新电影,所以他们应该能够将该数据保存到他们读取的同一个文件中。但这是我想先测试自己的东西,然后再四处寻求帮助。
您只读了一个条目就从循环体返回。如果您真的想读取文件中的所有条目,则需要将读取循环更改为读取数组,实际上,由于 fread
的工作原理,您可以将其全部删除:
// main functions --- read from file
// ================================================================
int
readFile(const char* fileName)
{
//open file
FILE* read = fopen(fileName, "rb");
if (!read)
{
printf("ERROR: Could not open the file!\n");
return 0; // note that since you'll probably assign the output to movieCount, it might be better to return 0 on failure
}
else
{
printf("%s were opened successfully.\n\n", fileName);
}
// Here's where the problem, you only ever read out one movie entry into movieRecord and returned
// You can use fread to read out the entire file into the array instead
// It would also be better not to use a global variable for this, instead taking in a pointer to an movie_t array to readFile instead but I left it using the global as per the original program
size_t count = fread(movieData, sizeof(movie_t), MAX_STORAGE, read);
if (ferror(read))
{
printf("ERROR: Read process was unsuccessful or incomplete!\n");
fclose(read);
return 0;
}
if (count == 1)
{
printf("Successfully read %i movie.\n", count);
}
else
{
printf("Successfully read %i movies.\n", count);
}
fclose(read);
return count;
}
从这里开始,您将 movieData
填充文件中的数据,并应相应地调整程序的其余部分。
我已经将我的代码缩减到最少,我认为这就是我解决问题所需的一切。
我希望用户能够阅读这个结构:
typedef struct {
char movieTitle[30];
unsigned int yearPublished;
char director[50];
char genre[50];
float profit;
} movie_t;
来自一个已经有 4 部电影的二进制文件,但也应该能够存储最多 100 部电影结构,如下定义:
//global var.
// ================================================================
#define MAX_STORAGE 100
movie_t movieData[MAX_STORAGE];
movie_t movieRecord;
unsigned int movieCount = 0;
使用我已经在下面编写的代码,我无法以某种方式从文件中读取所有电影,因为我的“计数检查器”每次都告诉我只读取了一部电影。在我的“readFile”函数下方的控制台输出代码中也只显示了一部电影。
// main functions --- read from file
// ================================================================
int
readFile(const char* fileName)
{
//open file
FILE* read = fopen(fileName, "rb");
if (!read)
{
printf("ERROR: Could not open the file!\n");
return -1;
}
else
{
printf("%s were opened successfully.\n\n", fileName);
}
//read from file
int count = 0;
while (!feof(read))
{
size_t count = fread(&movieRecord, sizeof(movieRecord), 1, read);
if (count == 0)
{
printf("ERROR: Read process was unsuccessful or incomplete!\n");
}
if (count == 1)
{
printf("Successfully read %i movie.\n", count);
}
else
{
printf("Successfully read %i movies.\n", count);
}
return count;
}
fclose(read);
return 0;
}
这是应该显示文件中所有电影的控制台输出。此外,它们应该显示 1 - 100 之间的数字 (Num.)。
// main functions --- console Output
// ================================================================
void
consoleOutput(movie_t movieData2, unsigned index)
{
printf("MOVIE DATA Num. %u\n\n", index);
printf("Movie title : %s\n", movieData2.movieTitle);
printf("Publishing year : %u\n", movieData2.yearPublished);
printf("Director : %s\n", movieData2.director);
printf("Genre : %s\n", movieData2.genre);
printf("Profit : %.2f\n", movieData2.profit);
}
这是我的主要功能的样子,如果你想看的话:
// MAIN
// ================================================================
int main(void)
{
// defaultname for file
char fileName[50] = "movies.dat";
// variable for loop
int stopLoop = 0;
// loop
do {
// Output menu
printf("\nMENU:\n");
printf("(a) Show all movies\n");
printf("(o) Read moviefile\n");
printf("(q) Exit programm\n");
printf("\nYour choice: ");
// User input
char ch = _getch();
printf("%c\n\n", ch);
// Switch case for user input
switch (ch)
{
case 'q': // Exit programm
stopLoop = 1;
break;
case 'a': // Show all movies
consoleOutput(movieRecord, movieCount = readFile(fileName));
break;
case 'o': // Read moviefile
readFile(fileName);
break;
default:
printf("==> Invalid input!\n");
}
} while (!stopLoop);
return 0;
}
旁注:因为用户能够输入新电影,所以他们应该能够将该数据保存到他们读取的同一个文件中。但这是我想先测试自己的东西,然后再四处寻求帮助。
您只读了一个条目就从循环体返回。如果您真的想读取文件中的所有条目,则需要将读取循环更改为读取数组,实际上,由于 fread
的工作原理,您可以将其全部删除:
// main functions --- read from file
// ================================================================
int
readFile(const char* fileName)
{
//open file
FILE* read = fopen(fileName, "rb");
if (!read)
{
printf("ERROR: Could not open the file!\n");
return 0; // note that since you'll probably assign the output to movieCount, it might be better to return 0 on failure
}
else
{
printf("%s were opened successfully.\n\n", fileName);
}
// Here's where the problem, you only ever read out one movie entry into movieRecord and returned
// You can use fread to read out the entire file into the array instead
// It would also be better not to use a global variable for this, instead taking in a pointer to an movie_t array to readFile instead but I left it using the global as per the original program
size_t count = fread(movieData, sizeof(movie_t), MAX_STORAGE, read);
if (ferror(read))
{
printf("ERROR: Read process was unsuccessful or incomplete!\n");
fclose(read);
return 0;
}
if (count == 1)
{
printf("Successfully read %i movie.\n", count);
}
else
{
printf("Successfully read %i movies.\n", count);
}
fclose(read);
return count;
}
从这里开始,您将 movieData
填充文件中的数据,并应相应地调整程序的其余部分。