我提交了这个问题集,但我无法获得满分等级,因为退出代码“预计为0而不是1”。但是,如果你看一下代码(recover.c文件),退出代码是0.有什么问题?该程序完成它所做的一切,即读取损坏文件中的位并找到组成JPG文件的位并将它们写入单独的文件中。我遇到的唯一问题是上述退出代码问题。请帮忙!
recover.c文件
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include "bmp.h"
int main (void){
FILE* card_ptr = fopen("card.raw","r");
if (card_ptr == NULL){
fprintf(stderr,"File Not Found!");
return 1;
}
BYTE buffer[512];
bool found_jpg = false;
FILE* new_jpg_ptr;
int file_counter = 0;
while(fread(buffer,1,512,card_ptr)!=0x00){
if(buffer[0]== 0xff && buffer[1]== 0xd8 && buffer[2]==0xff && (buffer[3] & 0xf0)== 0xe0){
if(!found_jpg){
char filename[8];
sprintf(filename, "%03i.jpg", file_counter++);
found_jpg = true;
new_jpg_ptr = fopen(filename,"w");
if(new_jpg_ptr == NULL){
return 2;
}
fwrite(buffer,1,512,new_jpg_ptr);
}
else {
fclose(new_jpg_ptr);
char filename[8];
sprintf(filename, "%03i.jpg", file_counter++);
found_jpg = true;
new_jpg_ptr = fopen(filename,"w");
if(new_jpg_ptr == NULL){
return 3;
}
fwrite(buffer,1,512, new_jpg_ptr);
}
}
else {
if(found_jpg){
fwrite(buffer,1,512, new_jpg_ptr);
}
}
}
fclose(new_jpg_ptr);
fclose(card_ptr);
return 0;
}
bmp.h文件
/**
* BMP-related data types based on Microsoft's own.
*/
#include <stdint.h>
/**
* Common Data Types
*
* The data types in this section are essentially aliases for C/C++
* primitive data types.
*
* Adapted from https://msdn.microsoft.com/en-us/library/cc230309.aspx.
* See http://en.wikipedia.org/wiki/Stdint.h for more on stdint.h.
*/
typedef uint8_t BYTE;
typedef uint32_t DWORD;
typedef int32_t LONG;
typedef uint16_t WORD;
/**
* BITMAPFILEHEADER
*
* The BITMAPFILEHEADER structure contains information about the type, size,
* and layout of a file that contains a DIB [device-independent bitmap].
*
* Adapted from https://msdn.microsoft.com/en-us/library/dd183374(v=vs.85).aspx.
*/
typedef struct
{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} __attribute__((__packed__))
BITMAPFILEHEADER;
/**
* BITMAPINFOHEADER
*
* The BITMAPINFOHEADER structure contains information about the
* dimensions and color format of a DIB [device-independent bitmap].
*
* Adapted from https://msdn.microsoft.com/en-us/library/dd183376(v=vs.85).aspx.
*/
typedef struct
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} __attribute__((__packed__))
BITMAPINFOHEADER;
/**
* RGBTRIPLE
*
* This structure describes a color consisting of relative intensities of
* red, green, and blue.
*
* Adapted from https://msdn.microsoft.com/en-us/library/dd162939(v=vs.85).aspx.
*/
typedef struct
{
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;
答案 0 :(得分:0)
我遇到了同样的问题。我的程序按预期工作,没有明显的原因返回代码为1
。正如您所知,我还包含了一个头文件,其中包含一些定义。将这些定义放在核心文件中解决了我的问题。也许如果您将所需的定义从bmp.h
文件移到recover.c
,check50
就可以编译。
我的解决方案,如果您有兴趣。
// Recover any forgotten JPEGS from a given forensic image
# include <stdio.h>
# include <stdbool.h>
# include <stdint.h>
typedef uint8_t BYTE;
typedef struct
{
BYTE byte_1;
BYTE byte_2;
BYTE byte_3;
BYTE byte_4_min;
BYTE byte_4_max;
} __attribute__((__packed__))
SIG;
// declare helper function prototypes
int check_args(int argc, char *argv[]);
bool signature_is_present(BYTE potential_sig[4], SIG jpeg_sig);
SIG set_jpeg_signature(void);
// main program
int main (int argc, char *argv[])
{
// check input for validity
int check_args_value = check_args(argc, argv);
if (check_args_value != 0)
{
return check_args_value;
}
// call function to set default jpeg signature
SIG jpeg_sig = set_jpeg_signature();
// open buffers and declare other necessary variables for later use
BYTE FAT_block[512];
BYTE first_byte[1];
int signature_offset = -4;
int counter = 0;
// open forensic image
FILE * inptr = fopen(argv[1], "r");
FILE * outptr = NULL;
// loop through file searching for first '255'
while (fread(first_byte, sizeof(BYTE), 1, inptr) == 1)
{
// check if byte is 255, the first byte of a jpeg signature
if (*first_byte == jpeg_sig.byte_1)
{
// check for signature
BYTE possible_sig[4];
// back pointer up one byte to compensate for already discovered 255
fseek(inptr, -1, SEEK_CUR);
// read four bytes from file that could potentially be a signature.
fread(possible_sig, sizeof(possible_sig), 1, inptr);
if (signature_is_present(possible_sig, jpeg_sig))
{
// close previously open write file, if any.
if (outptr != NULL)
{
fclose(outptr);
//Increment counter for image signatures found.
counter++;
}
// setup name for image file
char file_name[8] = {};
snprintf(file_name, 8, "%.3i.jpg\n", counter);
// move pointer back 4 bytes after checking what they contain
fseek(inptr, signature_offset, SEEK_CUR);
//read FAT block from forensic image into buffer
fread(FAT_block, sizeof(FAT_block), 1, inptr);
// open new output file based on current signature
outptr = fopen(file_name, "w");
// write FAT block buffer to file
fwrite(FAT_block, sizeof(FAT_block), 1, outptr);
}
else // byte is 255 but not part of a signature
{
if (outptr != NULL)
{
// move pointer back 4 bytes after checking what they contain
fseek(inptr, signature_offset, SEEK_CUR);
//read FAT block from forensic image into buffer
fread(FAT_block, sizeof(FAT_block), 1, inptr);
// write FAT block buffer to file
fwrite(FAT_block, sizeof(FAT_block), 1, outptr);
}
}
}
else // if byte is not 255
{
if (outptr != NULL)
{
//back up one byte
fseek(inptr, -1, SEEK_CUR);
//read FAT block from forensic image into buffer
fread(FAT_block, sizeof(FAT_block), 1, inptr);
// write FAT block buffer to file
fwrite(FAT_block, sizeof(FAT_block), 1, outptr);
}
}
}
// close files
fclose(inptr);
if (outptr != NULL)
{
fclose(outptr);
}
return 0;
}
// helper functions
int check_args(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Invalid Input.\nForensic image file must be provided.\n");
return 1;
}
FILE *inptr = fopen(argv[1], "r");
if (inptr == NULL)
{
fprintf(stderr, "File does not exist.\n");
return 2;
}
fclose(inptr);
return 0;
}
bool signature_is_present(BYTE potential_sig[4], SIG jpeg_sig)
{
if( potential_sig[0] == jpeg_sig.byte_1 &&
potential_sig[1] == jpeg_sig.byte_2 &&
potential_sig[2] == jpeg_sig.byte_3 &&
potential_sig[3] >= jpeg_sig.byte_4_min &&
potential_sig[3] <= jpeg_sig.byte_4_max )
{
return true;
}
return false;
}
SIG set_jpeg_signature(void)
{
SIG jpeg_sig;
jpeg_sig.byte_1 = 255;
jpeg_sig.byte_2 = 216;
jpeg_sig.byte_3 = 255;
jpeg_sig.byte_4_min = 224;
jpeg_sig.byte_4_max = 239;
return jpeg_sig;
}