CS50 PSET4 恢复:fread() 未填充缓冲区数组
CS50 PSET4 RECOVER: fread() not populating buffer array
您好,感谢您的浏览。
我正在研究 CS50x,并且正在努力 恢复。目的是打开一个 .raw 文件,以 512 字节的块读取其内容,检查 .jpg 的前四个字节 headers,然后将每个 JPEG 数据写入一个新文件。
我编写了 body 代码,文件编译成功。调试器告诉我,我的 buffer[512] 变量仍然是 empty/zeroed。这意味着程序会跳过 if/else 条件并退出。
虽然我在 While 循环中的逻辑可能有缺陷,但我还没有深入到程序中来考虑这一点。
我在发布之前查看了我的问题。有些来源喜欢使用 fread(buffer, 512, 1, input)
,但 CS50 本身使用 fread(buffer, 1, 512, input)
。此外,在初始化文件名时,我尝试了 char *filename = malloc(8 * sizeof(char));
和 char filename[8];
。对于这两行,我都尝试了每种方法,但仍然缺少一些东西。
我的代码如下。预先感谢您的宝贵时间。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
// First check the number of arguments is correct.
if (argc != 2)
{
printf("Correct Usage: ./recover.c [filename]\n");
return 1;
}
// Open the file.
FILE *inputFile = fopen(argv[1], "r");
if (inputFile == NULL)
{
printf("File not found.\n");
return 1;
}
// Create counter of number of files.
int counter = 0;
// Create filename variable
char *filename = malloc(8 * sizeof(char)); // 7 + 1 for [=10=]
// Create a 512-size array buffer.
BYTE buffer[512];
// Initialise img file for scope access.
FILE *img = NULL;
while (fread(buffer, sizeof(BYTE), 512, inputFile))
{
// If start of new JPEG:
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
if (counter == 0) // If the FIRST JPEG
{
// Make new file:
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
fwrite(buffer, sizeof(BYTE), 512, img);
}
else // If not the first JPEG
{
fclose(img); // Close previous file.
counter++;
// Make new file:
sprintf(filename, "%03i.jpg", counter); // Update filename.
img = fopen(filename, "w");
fwrite(buffer, sizeof(BYTE), 512, img);
}
}
else if (counter > 0) // buffer is continuation of previous.
{
fwrite(buffer, sizeof(BYTE), 512, img);
}
else
{
printf("I exited with no images.\n");
return 2;
}
}
free(filename);
fclose(img);
fclose(inputFile);
return 0;
}
读取原始文件中的第一行后程序退出 (returns)(假设它不是 jpeg header,发行版原始文件就是这种情况)。 else if (counter > 0)
计算结果为 false,因此执行 else
分支。
谢谢大家的回复。问题现已解决!
@DinoCoderSaurus(抱歉,还不能投票)促使我意识到我曾(错误地)假设原始文件中的数据会立即以 .jpeg header 开头(事实上看起来数据以隐藏消息“惊喜”开头)。
Else
条件最初放在那儿是为了避免错误,但当然它会过早地退出 While 循环。几次循环后缓冲区被正确填充。
然后我遇到了第二个问题(@Some_programmer_dude指出)counter++;
写错了,也就是说在第一个新的JPEG之后,其他的就写不出来了。
我也会考虑您对最佳做法的意见。
您好,感谢您的浏览。
我正在研究 CS50x,并且正在努力 恢复。目的是打开一个 .raw 文件,以 512 字节的块读取其内容,检查 .jpg 的前四个字节 headers,然后将每个 JPEG 数据写入一个新文件。
我编写了 body 代码,文件编译成功。调试器告诉我,我的 buffer[512] 变量仍然是 empty/zeroed。这意味着程序会跳过 if/else 条件并退出。
虽然我在 While 循环中的逻辑可能有缺陷,但我还没有深入到程序中来考虑这一点。
我在发布之前查看了我的问题。有些来源喜欢使用 fread(buffer, 512, 1, input)
,但 CS50 本身使用 fread(buffer, 1, 512, input)
。此外,在初始化文件名时,我尝试了 char *filename = malloc(8 * sizeof(char));
和 char filename[8];
。对于这两行,我都尝试了每种方法,但仍然缺少一些东西。
我的代码如下。预先感谢您的宝贵时间。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
// First check the number of arguments is correct.
if (argc != 2)
{
printf("Correct Usage: ./recover.c [filename]\n");
return 1;
}
// Open the file.
FILE *inputFile = fopen(argv[1], "r");
if (inputFile == NULL)
{
printf("File not found.\n");
return 1;
}
// Create counter of number of files.
int counter = 0;
// Create filename variable
char *filename = malloc(8 * sizeof(char)); // 7 + 1 for [=10=]
// Create a 512-size array buffer.
BYTE buffer[512];
// Initialise img file for scope access.
FILE *img = NULL;
while (fread(buffer, sizeof(BYTE), 512, inputFile))
{
// If start of new JPEG:
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
if (counter == 0) // If the FIRST JPEG
{
// Make new file:
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
fwrite(buffer, sizeof(BYTE), 512, img);
}
else // If not the first JPEG
{
fclose(img); // Close previous file.
counter++;
// Make new file:
sprintf(filename, "%03i.jpg", counter); // Update filename.
img = fopen(filename, "w");
fwrite(buffer, sizeof(BYTE), 512, img);
}
}
else if (counter > 0) // buffer is continuation of previous.
{
fwrite(buffer, sizeof(BYTE), 512, img);
}
else
{
printf("I exited with no images.\n");
return 2;
}
}
free(filename);
fclose(img);
fclose(inputFile);
return 0;
}
读取原始文件中的第一行后程序退出 (returns)(假设它不是 jpeg header,发行版原始文件就是这种情况)。 else if (counter > 0)
计算结果为 false,因此执行 else
分支。
谢谢大家的回复。问题现已解决!
@DinoCoderSaurus(抱歉,还不能投票)促使我意识到我曾(错误地)假设原始文件中的数据会立即以 .jpeg header 开头(事实上看起来数据以隐藏消息“惊喜”开头)。
Else
条件最初放在那儿是为了避免错误,但当然它会过早地退出 While 循环。几次循环后缓冲区被正确填充。
然后我遇到了第二个问题(@Some_programmer_dude指出)counter++;
写错了,也就是说在第一个新的JPEG之后,其他的就写不出来了。
我也会考虑您对最佳做法的意见。