我可以做一些建议,对我来说,这在逻辑上是合理的,但是当我运行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
我看到的一个错误是 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;
}
关于。
printf("File not found/n");
错误信息应输出到 stderr
,不 stdout
.
当错误指示来自于C库函数时,也应该输出到 stderr
,系统认为发生错误的文本原因。函数:perror( "your error msg" )。
就是为了这个目的而制作的。
关于。
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)
捕捉EFO和部分读取以及IO错误。
关于。
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)
的长度,所以它可能会错过与下一个图像的相遇,并可能导致下一个图像的部分标题等数据被写入当前输出文件。
请把这个函数贴出来。
is_jpeg_header(buffer)
因为它不可能纠正上面列出的问题。