CS50第4周恢复,加载000.jpg时出现问题,每隔一个图像都很好

dz6r00yl  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(68)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

//Creates a new variable BYTE that stores a BYTE of data
typedef uint8_t BYTE;

int main(int argc, char *argv[])
{
    //Incorrect Number of CLA
    if (argc != 2){
        printf("Improper Usage\n");
        return 1;
    }
    //Incorrect Files Inputted
    if (argv[1] == NULL){
        printf("Usage: ./recover IMAGE\n");
    }

    //initializing the buffer
    BYTE buffer[512];

    //Open the Memory Card and Initialize the file pointer pointing towards it ----- fread
    FILE *f = fopen(argv[1], "r");

    //variable for filename
    int count = 0;

    //create a new block of memory to store the filename
    char *filename = malloc(8);

    //Set the name of the string to later name the file
    sprintf(filename, "%03i.jpg", count);

    //creating a new file with the name set
    FILE *new_file = fopen(filename, "w");

    if (new_file == NULL) {
        fprintf(stderr, "Failed to open file: %s\n", filename);
        free(filename);
        fclose(f);
        return 1;
    }

    //while loop that runs till the end of the file
    while (fread(buffer, 1, 512, f) == 512){
        //Look for the beginning of a JPEG file ( 0xff, 0xd8, 0xff, 0xe0) ----- &0xf0
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0){
            if (count == 0){
                //writing the block of 512 bytes to the new file
                fwrite(buffer, 1, 512, new_file);

                //increase the count according to the number of file
                count++;
            } else {
                fclose(new_file);
                sprintf(filename, "%03i.jpg", count);
                count++;
                new_file = fopen(filename, "w");
                fwrite(buffer, 1, 512, new_file);
            }
        }else{
            //writing the data contiguosly stored in the memory card
            fwrite(buffer, 1, 512, new_file);
        }
    }
    //free
    fclose(f);
    fclose(new_file);
    free(filename);
}

字符串
由于问题出现在第一个jpeg 000.jpg中,我猜它与if(count == 0)部分有关。但似乎能想明白。我尝试在while循环外初始化new_file,并在if条件中打开它。但它不工作。
请告诉我可能是什么问题。

sgtfey8w

sgtfey8w1#

代码至少存在以下问题:

二进制模式

.jpg文件应以 binary 模式打开

// fopen(filename, "w");
fopen(filename, "wb");

字符串

缓冲区溢出风险

count > 999时,缓冲区太小。

// char *filename = malloc(8);
char *filename = malloc(15);
sprintf(filename, "%03i.jpg", count);


搜索snprintf()

如果文件长度不是512的倍数怎么办?

OP的代码不能很好地处理这种情况。

//while loop that runs till the end of the file
while (fread(buffer, 1, 512, f) == 512){


不清楚OP的目标是什么。

检查错误

检查fopen()malloc()fwrite()的返回值。@哈里斯。

设计缺陷

代码很奇怪,如果读取的第一个块不符合buffer[0] == 0xff && buffer[1] == 0xd8 ...,它会被写入“000.jpg”。也许应该扔掉。

相关问题