CS50 PSET4恢复:Fread()不填充缓冲区数组
您好,谢谢您的看看。
我正在通过CS50X工作,并且正在努力恢复。目的是打开一个.raw文件,在512个字节块中读取其内容,检查.jpg标头的最初的四个字节,然后将每个JPEG数据写入新文件。
我写了一个代码的主体,文件编译。调试器告诉我,我的缓冲区[512]变量保持空/零。然后,这意味着如果/其他条件和程序退出,则该程序会跳过。
尽管我的逻辑可能会存在缺陷,但我无法进入程序足够远,无法考虑这一点。
发布之前,我查找了问题。一些来源喜欢使用fread(缓冲区,512,1,输入)
,但是CS50本身使用fread(Buffer,1,512,Input)
。另外,在初始化文件名时,我已经尝试了char * filename = malloc(8 * sizeof(char));
and 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 \0
// 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;
}
Hello and thank you for taking a look.
I'm working through CS50x and am struggling with Recover. The aim is to open a .raw file, read its contents in 512-byte blocks, check the initial four bytes for .jpg headers, and then write each JPEG data to a new file.
I have a body of code written, and the file compiles. The debugger tells me that my buffer[512] variable remains empty/zeroed. This then means the program skips if/else conditions and the program exits.
While my logic within the While loop may be flawed, I haven't been able to step far enough into the program to consider this.
I looked up my issue before posting. Some sources like to use fread(buffer, 512, 1, input)
, but CS50 itself uses fread(buffer, 1, 512, input)
. Also, when initialising the filename, I have tried both char *filename = malloc(8 * sizeof(char));
and char filename[8];
. For both lines I have tried each method and am still missing something.
My code is below. Thank you in advance for your time.
#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 \0
// 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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
读取原始文件中的第一行后,程序退出(返回)(假设它不是 jpeg 标头,发行版原始文件就是这种情况)。
else if (counter > 0)
计算结果为 false,因此执行else
分支。The program exits (returns) after the first line in the raw file is read (assuming it's not a jpeg header, which is the case with the distro raw file).
else if (counter > 0)
evaluates to false, so theelse
branch executes.谢谢大家的回复。现在问题已解决!
@dinocodersaurus(对不起,尚无法投票)提示我意识到我(错误地)以.jpeg标头开始立即(实际上,看起来数据都以隐藏的消息开头) , “惊喜”)。
else
条件最初是为了避免错误的情况,但是当然,它已过早地退出时循环。几个循环后正确填充缓冲区。然后,我遇到了第二个问题(由@some_programmer_dude指出),
counter ++;
在错误的位置,这意味着在第一个新的JPEG之后,没有其他内容。我还将考虑您的最佳实践评论。
Thank you everyone for your response. The issue is now fixed!
@DinoCoderSaurus (sorry, can't upvote yet) prompted me to realise that I had assumed (wrongly) that the data in the raw file would immediately begin with a .jpeg header (in fact it looks like the data begins with a hidden message, "surprise").
The
Else
condition was initially put there to avoid errors but of course it was prematurely exiting the While loop. The buffer was populated correctly after a couple of loops.I then encountered the second problem (pointed out by @Some_programmer_dude) that
counter++;
was in the wrong place, which meant after the first new JPEG, no others could be written.I'll also take your comments about best practice into consideration.