提问人:ckwan 提问时间:7/14/2020 更新时间:7/14/2020 访问量:176
使用 feof 函数退出文件
Exiting out of file with feof function
问:
我正在尝试使照片提取程序在检测到它位于要提取的文件的末尾时停止。我通过放置一个 if 条件来做到这一点:
if (feof(file))
{
return 2;
}
在 fread 函数之后:
fread(array, 1, 512, file);
因此,如果 fread 读取到文件末尾,则 feof 将触发并结束程序。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Invalid entry.\n");
return 0;
}
int counter = 1;
FILE* images;
char jpg_name[8];
// Check if bytes are jpg. signatures.
for (int n = 0; counter < 51; n = n + 512)
{
// Open file for reading.
FILE *file = fopen(argv[1], "r");
if (!file)
{
return 1;
}
unsigned char array[512];
fseek(file, n, SEEK_SET);
fread(array, 1, 512, file); // if EOF, won't have 512 to write into!!!
if (feof(file))
{
return 2;
}
fclose(file);
if (array[0] == 0xff && array[1] == 0xd8 && array[2] == 0xff && (array[3] & 0xf0) == 0xe0)
{
// Convert integer to string and store into jpg character array. Increment image number.
sprintf(jpg_name, "%03i.jpg", counter);
counter++;
// Open images file to write into, allocate memory to jpg file to write into, write 512 bytes from array into image file.
images = fopen(jpg_name, "a");
fwrite(array, 1, 512, images);
fclose(images);
}
else // If 1st 4 bytes aren't jpg signature.
{
if (counter > 1)
{
images = fopen(jpg_name, "a");
fwrite(array, 1, 512, images);
fclose(images);
}
}
}
}
我还尝试过放置条件:
if (fread(array, 1, 512, file) == 512)
进入程序,使其在读取少于 512 字节后停止运行,以停止自动停止程序,但这似乎也不起作用。
任何澄清或建议将不胜感激,谢谢!
答:
0赞
Barmar
7/14/2020
#1
不要每次都打开和关闭文件。只需读取块中的文件,直到到达 EOF。512
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define SIZE 512
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Invalid entry.\n");
return 0;
}
int counter = 1;
FILE* images;
char jpg_name[8];
// Open file for reading.
FILE *file = fopen(argv[1], "r");
if (!file)
{
return 1;
}
unsigned char array[SIZE];
// Check if bytes are jpg. signatures.
while (fread(array, 1, SIZE, file) == 1)
{
if (array[0] == 0xff && array[1] == 0xd8 && array[2] == 0xff && (array[3] & 0xf0) == 0xe0)
{
// Convert integer to string and store into jpg character array. Increment image number.
sprintf(jpg_name, "%03i.jpg", counter);
counter++;
// Open images file to write into, allocate memory to jpg file to write into, write 512 bytes from array into image file.
images = fopen(jpg_name, "a");
fwrite(array, 1, 512, images);
fclose(images);
}
else // If 1st 4 bytes aren't jpg signature.
{
if (counter > 1)
{
images = fopen(jpg_name, "a");
fwrite(array, 1, 512, images);
fclose(images);
}
}
}
fclose(file);
}
评论
0赞
user3629249
7/15/2020
关于:这不是一个正确的比较。它是调用成功时将返回的第三个参数值。即while (fread(array, 1, SIZE, file) == 1)
while ( fread( array, 1, SIZE, file ) == SIZE )
0赞
user3629249
7/15/2020
一遍又一遍地打开/关闭文件是一个糟糕的主意。强烈建议仅使用“4 jpg 标头”字节作为(可能)关闭先前输出文件然后打开新文件的原因
0赞
Barmar
7/15/2020
@user3629249我最初将其移出循环,然后注意到文件名取决于 .我不想用确定何时打开和关闭文件所需的所有逻辑使答案复杂化。实际上并没有那么多开销,因此解决这个问题很重要。counter
0赞
user3629249
7/15/2020
实际上,打开/关闭文件是最有可能发生 I/O 错误的时候。因此,代码应尽量减少这些事件的数量
0赞
Barmar
7/15/2020
@user3629249 或者可能相反,因此您可以尽早发现错误。
评论
argv[1]
jpg_name
feof
feof
fread