代码一次读取512字节,并将它们存储在缓冲区中。当代码看到一个.jpeg签名时,它将继续写入一个.jpeg文件,直到找到另一个签名为止,然后这个过程会重复。
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#define infile "card.raw"
#define BLOCK 512
/**
* recover.c
*
* Computer Science 50
* Problem Set 4
*
* Recovers JPEGs from a forensic image.
*/
// Declarations and prototype(s)
char * name();
FILE* outptr = NULL;
int increment = 0;
int main(void)
{
// Open input file, plus error check
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)
{
printf("Could not open %s.\n", infile);
return 3;
}
// Allocate memory for one BLOCK and read from infile
unsigned char * buffer = malloc(BLOCK);
if (buffer == NULL)
return 3;
while (fread(buffer, BLOCK, 1, inptr) != 0) {
/* Shall modify to operate on bitwise operations in the future. */
// If the first four bytes of buffer is equal to a jpg file signature,
// then copy all contents to a new jpg until another signature is found
if (buffer[0] == 0xff &&
buffer[1] == 0xd8 &&
buffer[2] == 0xff &&
buffer[3] >= 0xe0 && buffer[3] <= 0xef) {
// If outptr does not yet refer to a file, close it
if (outptr != NULL)
fclose(outptr);
// Open ###th output file, plus error-checking
outptr = fopen(name(), "w");
if (outptr == NULL) {
fprintf(stderr, "Could not create outfile.\n");
fclose(outptr);
return 3;
}
}
if (outptr != NULL)
fwrite(buffer, BLOCK, 1, outptr);
}
// Check if the file was looped through correctly
if ( !(feof(inptr)) )
return 3;
free(buffer);
fclose(inptr);
return 0;
}
// Name files incrementally starting from '000'
int filenum = 0;
char filename[7];
char * name()
{
if (filenum < 10)
sprintf(filename, "00%d.jpg", filenum);
else
sprintf(filename, "0%d.jpg", filenum);
filenum++;
return filename;
}发布于 2016-09-04 19:25:34
您应该使用二进制模式来打开文件,而不是文本模式。因此,改变:
FILE* inptr = fopen(infile,"r");
至
FILE* inptr = fopen(infile, "rb");否则,当您不希望CR/LF字符转换时,它们可能会被转换。
您的文件名缓冲区太短:
7;char * name() { if (filenum < 10) sprintf(文件名,"00%d.jpg",filenum);否则sprintf(文件名,"0%d.jpg",filenum);// .
在这里,您的文件名将类似于"000.jpg",它需要7个字符加上一个终止空字符,或者总共需要8个字符。此外,如果您生成100个或更多文件,您将需要更多的字符。
带前导零的
有一种更好的方法来生成带有前导零填充的文件名。而不是:
如果(filenum < 10) sprintf(文件名,"00%d.jpg",filenum),其他sprintf(文件名,"0%d.jpg",filenum);
你可以这样做:
sprintf(filename, "%03d.jpg", filenum);https://codereview.stackexchange.com/questions/140496
复制相似问题