简体   繁体   English

CS50 PSET4 recover.c - 我只恢复了 25 jpg

[英]CS50 PSET4 recover.c - Im recovering only 25 jpg's

Im doing CS50 course and in stuck on PSET4.我正在学习 CS50 课程并卡在 PSET4 上。 I have written a code that recovers JPG's from card.raw.我编写了一个从 card.raw 中恢复 JPG 的代码。 Problem is that i only get 25 picks (from 000.jpg to 024.jpg) after running my program, and there should be 50 of them.问题是我在运行我的程序后只得到 25 个选择(从 000.jpg 到 024.jpg),应该有 50 个。 I dont have a clue why is this happening.我不知道为什么会这样。 Could You give me a pointer:)能给我指点吗:)

My code:我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

char *name[9] = {"card.raw"};
int i;
int a = -1;
char recovered[sizeof "050.jpg"];


uint8_t buffer[512];

int main(int argc, char *argv[])
{
    //Check for valid quantity of command line arguments
    if (argc != 2 || (strcmp (argv[1], *name) != 0))
    {
    printf("Usage: ./recover image\n");
    return 1;
    }

    FILE *card = fopen(argv[1], "r");

    //Check if file card.raw exists
    if (card == NULL)
    {
        printf("Could not open file\n");
        return 1;
    }

    while(fread(&buffer, 512, 1, card))
    {
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && ((buffer[3] & 0xf0) == 0xe0))
        {
            a++;
            sprintf(recovered, "%03d.jpg", a);
            FILE *output = fopen(recovered,"w");
            if (output == NULL)
            {
                printf("Could not create file %03d/n",a);
                return 1;
            }
            fwrite(buffer, 512, 1, output);


            while(fread(&buffer, 512, 1, card))
            {
                 if ( !(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && ((buffer[3] & 0xf0) == 0xe0)))
                 {
                     fwrite(buffer, 512, 1, output);
                 }
                 else
                 {
                     break;
                 }

            }
            fclose(output);

        }
    }
    fclose(card);
    return 0;
}

There are several issues.有几个问题。

You have two nested loops.你有两个嵌套循环。 You want only one .你只想要一个

When the inner loop detects a header, you break out of the loop.当内部循环检测到 header 时,您将跳出循环。

But, only the outer loop opens the output file.但是,只有外循环打开 output 文件。

It does a new read, so it will never see the header that the inner loop detected, and will not open the next output file.它进行了新的读取,因此它永远不会看到内部循环检测到的 header,并且不会打开下一个 output 文件。

So, you only get half as many output files.因此,您只能获得一半的 output 文件。 And, they're all corrupt because they have the header and data from the first file and have only the data from the second one.而且,它们都已损坏,因为它们具有 header 和第一个文件中的数据,而只有第二个文件中的数据。 This repeats alternately throughout.这在整个过程中交替重复。

FILE *output is loop scoped. FILE *output是循环范围的。 It should be function scoped.它应该在 function 范围内。

recovered is defined in an unconventional way. recovered的定义非常规。 Better to just define it with a large amount.最好只用大量来定义它。 This prevents the compiler from flagging it as too small.这可以防止编译器将其标记为太小。 The compiler assumes that a could be (eg) 1000000000 and the sprintf would overflow the size of recovered编译器假设a可以是(例如)1000000000 并且sprintf会溢出recovered的大小

name is also defined in an unorthodox manner. name也以非正统的方式定义。

i is never used. i从未使用过。


Here's a refactored and annotated version.这是一个重构和注释的版本。 It compiles but I've not tested it:它可以编译,但我没有测试过:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

const char *name = "card.raw";

int a = -1;
char recovered[1000];

uint8_t buffer[512];

int
main(int argc, char **argv)
{

    // Check for valid quantity of command line arguments
    if (argc != 2 || (strcmp(argv[1], name) != 0)) {
        printf("Usage: ./recover image\n");
        return 1;
    }

    FILE *card = fopen(argv[1], "r");

    // Check if file card.raw exists
    if (card == NULL) {
        printf("Could not open file\n");
        return 1;
    }

    FILE *output = NULL;

    while (fread(buffer, sizeof(buffer), 1, card)) {
        // detect new input header
        if ((buffer[0] == 0xff) && (buffer[1] == 0xd8) &&
            (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0)) {

            // close previous output stream
            if (output != NULL)
                fclose(output);

            // open new output stream
            ++a;
            sprintf(recovered, "%03d.jpg", a);
            output = fopen(recovered, "w");
            if (output == NULL) {
                printf("Could not create file %03d/n", a);
                return 1;
            }
        }

        // write data to output stream
        // this writes both the header and data for a given output file
        if (output != NULL)
            fwrite(buffer, sizeof(buffer), 1, output);
    }

    // close the last output stream
    if (output != NULL)
        fclose(output);

    fclose(card);

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM