首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在查找.raw签名时读取.jpeg文件

在查找.raw签名时读取.jpeg文件
EN

Code Review用户
提问于 2016-09-04 18:27:02
回答 1查看 1.5K关注 0票数 4

代码一次读取512字节,并将它们存储在缓冲区中。当代码看到一个.jpeg签名时,它将继续写入一个.jpeg文件,直到找到另一个签名为止,然后这个过程会重复。

代码语言:javascript
复制
#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;
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2016-09-04 19:25:34

二进制模式

您应该使用二进制模式来打开文件,而不是文本模式。因此,改变:

FILE* inptr = fopen(infile,"r");

代码语言:javascript
复制
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个或更多文件,您将需要更多的字符。

带前导零的

Pad字符串

有一种更好的方法来生成带有前导零填充的文件名。而不是:

如果(filenum < 10) sprintf(文件名,"00%d.jpg",filenum),其他sprintf(文件名,"0%d.jpg",filenum);

你可以这样做:

代码语言:javascript
复制
sprintf(filename, "%03d.jpg", filenum);
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/140496

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档