我可以为此提供一些建议,对我来说这在逻辑上是有意义的,但是当我运行check50时,仅恢复了其中一张图像。我已经多次检查了代码,所以我认为它不是语法错误,因此逻辑上一定有错误。任何提示将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <cs50.h>
typedef uint8_t BYTE;
bool is_jpeg_header(BYTE buffer[]);
int main(int argc, char *argv[])
{
// Check if command line argument is valid
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
// Open memory card files
char* mem_card = argv[1];
FILE* inptr = fopen(mem_card, "r");
if (inptr == NULL)
{
printf("File not found/n");
return 1;
}
BYTE buffer[512];
bool found_first_jpeg = false;
int image_count = 0;
char filename[8];
FILE* outptr = NULL;
while (!feof(inptr) && fread(buffer, sizeof(buffer), 1, inptr) == true)
{
// Check if we have found a JPEG
if (is_jpeg_header(buffer) == true)
{
// Check if this is the first JPEG
if (found_first_jpeg == false)
{
found_first_jpeg = true;
sprintf(filename, "%03i.jpg", image_count);
outptr = fopen(filename, "w");
fwrite(buffer, sizeof(buffer), 1, outptr);
image_count++;
}
// If this isn't the first JPEG, close file current JPEG and open new one for new JPEG
else
{
fclose(outptr);
image_count++;
sprintf(filename, "%03i.jpg", image_count);
outptr = fopen(filename, "w");
}
}
// If we haven't found a new JPEG:
else if (is_jpeg_header(buffer) == false)
{
// Continue reading file if we have not found first JPEG
if (found_first_jpeg == false)
{
continue;
}
// Continue writing current JPEG into current file
else
{
fwrite(buffer, sizeof(buffer), 1, outptr);
}
}
}
fclose(inptr);
fclose(outptr);
return 0;
}
bool is_jpeg_header(BYTE buffer[])
{
if (((buffer[0] == 0xff) && (buffer [1] == 0xd8) && (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0)))
{
return true;
}
return false;
}
这是我从check50收到的错误代码
:) recover.c exists.
:) recover.c compiles.
:) handles lack of forensic image
:) recovers 000.jpg correctly
:( recovers middle images correctly
001.jpg not found
:( recovers 049.jpg correctly
recovered image does not match
答案 0 :(得分:0)
我看到的一个错误是filename
太短:您没有为终止零留任何余地。这是不确定的行为,很可能是您的麻烦根源。
但是,就一个简单的问题而言,整个逻辑非常复杂。这是我的写法。由于您通常不检查错误,因此我以这种方式保留了它-尽管我尚未阅读,但对于该测试任务来说可能还可以。不过,它确实有助于为不同的错误返回不同的错误代码-原来的错字确实有帮助!
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
typedef uint8_t bool;
static const bool true = 1;
static const bool false = 0;
bool is_jpeg_header(const uint8_t buffer[]);
int main(int argc, char *argv[])
{
// Check if command line argument is valid
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
// Open the memory card image
char* mem_card = argv[1];
FILE* infile = fopen(mem_card, "r");
if (!infile)
{
printf("File not found/n");
return 2;
}
uint8_t buffer[512];
int image_count = 0;
char filename[9];
FILE* outfile = NULL;
while (!feof(infile) && fread(buffer, sizeof(buffer), 1, infile) == 1)
{
// Check if we have found a JPEG
if (is_jpeg_header(buffer))
{
// If we're already writing output - close it
if (outfile)
fclose(outfile);
sprintf(filename, "%03i.jpg", image_count);
outfile = fopen(filename, "w");
image_count ++;
}
// Write the output if we're ready to write
if (outfile)
fwrite(buffer, sizeof(buffer), 1, outfile);
}
fclose(infile);
fclose(outfile);
return 0;
}
bool is_jpeg_header(const uint8_t buffer[])
{
return
buffer[0] == 0xff
&& buffer[1] == 0xd8
&& buffer[2] == 0xff
&& (buffer[3] & 0xf0) == 0xe0;
}
答案 1 :(得分:0)
why while(!foef() is always wrong
关于:
printf("File not found/n");
错误消息应该输出到stderr
,而不是stdout
。
当错误指示来自C库函数时,也应该输出到stderr
,这是系统认为发生错误的文本原因。功能:
perror(“您的错误消息”);
是为此目的而制作的。
关于:
printf("Usage: ./recover image\n");
1)这应该是stderr
,而不是stdout
。 2)不要对可执行文件名称进行硬编码。建议:
fprintf( stderr, "Usage: %s imagefile\n". argv[0] );
关于:
while (!feof(inptr) && fread(buffer, sizeof(buffer), 1, inptr) == true)
1)true
和false
在stdbool.h
中定义,因此需要包括头文件。
2)fread()
返回读取的项目数。 (也是第三个参数,(并记住关于while( !foef() )
的先前语句,因此该语句最好写成:
while ( fread(buffer, sizeof(buffer), 1, inptr) == 1)
捕获EOF和部分读取以及I / O错误。
关于;
outptr = fopen(filename, "w");
对fopen()
的调用成功/失败不受程序控制,因此,请始终检查(!= NULL)返回值以确保操作成功。
关于:
if (is_jpeg_header(buffer) == false)
{ // Continue reading file if we have not found first JPEG
if (found_first_jpeg == false)
{
continue;
} // Continue writing current JPEG into current file
else
此代码可以完全删除
启动第二个文件后,发布的代码无法关闭当前输出文件。
发布的代码始终读取sizeof(buffer)
个字节(假定没有错误),但不能保证每个图像数据的长度都是sizeof(buffer)
的倍数,因此它可能会错过与下一个图像的相遇AND可能导致下一张图片的标题等数据被写入当前输出文件。
请发布功能:
is_jpeg_header(buffer)
因为不可能纠正上面列出的问题。