Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CS5Ox Pset4恢复:代码仅恢复部分映像_C_Cs50 - Fatal编程技术网

CS5Ox Pset4恢复:代码仅恢复部分映像

CS5Ox Pset4恢复:代码仅恢复部分映像,c,cs50,C,Cs50,我有一些CS50 Pset4的半工作代码。如果您运行它,您将看到它恢复了27个jpg文件,但只有前几行是可见的 有人能给我指出正确的方向吗 #include <stdio.h> #include <stdint.h> #include <stdlib.h> typedef uint8_t BYTE; int main (int argc, char *argv[]) { // ensure proper usage if (argc !=

我有一些CS50 Pset4的半工作代码。如果您运行它,您将看到它恢复了27个jpg文件,但只有前几行是可见的

有人能给我指出正确的方向吗

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

typedef uint8_t BYTE;

int main (int argc, char *argv[])
{
    // ensure proper usage
    if (argc != 2)
    {
        fprintf(stderr, "Usage: ./recover infile\n");
        return 1;
    }

    // open file to be recovered
    FILE *infile = fopen(argv[1], "r");
    if (infile == NULL)
    {
        fprintf(stderr, "Could not open infile.\n");
        return 2;
    }

    // temp storage for blocks
    BYTE buffer[512];

    // variable to store filename
    char filename[8];

    //store number of recovered files
    int n = 0;

    // temp storage for outfiles
    FILE* outfile = NULL;

    // iterate over all blocks of memory until end of SD card is reached
    while (fread(buffer, 512, 1, infile) != 0)
    {
        // read one block
        fread(buffer, 512, 1, infile);

        // check if block is start of jpeg
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            //close previous file if already open
            if(outfile != NULL)
            {
                fclose(outfile);
            }

            // creeate new outfile
            sprintf(filename, "%03i.jpg", n);
            outfile = fopen(filename, "w");

            // write block to outfile
            fwrite(buffer, 512, 1, outfile);

            n++;
        }
        else
        {
            // write block to current outfile
            if(outfile != NULL)
            {
                fwrite(buffer, 512, 1, outfile);
            }
        }
    }

    //close last outfile
    fclose(outfile);

    //close infile
    fclose(infile);
}
#包括
#包括
#包括
typedef uint8_t字节;
int main(int argc,char*argv[])
{
//确保正确使用
如果(argc!=2)
{
fprintf(标准,“用法:./recover infle\n”);
返回1;
}
//打开要恢复的文件
文件*infle=fopen(argv[1],“r”);
if(infle==NULL)
{
fprintf(stderr,“无法打开内嵌。\n”);
返回2;
}
//块的临时存储
字节缓冲区[512];
//用于存储文件名的变量
字符文件名[8];
//存储恢复的文件数
int n=0;
//输出文件的温度存储
FILE*outfile=NULL;
//迭代所有内存块,直到到达SD卡的末尾
while(fread(缓冲区,512,1,infle)!=0)
{
//读一块
fread(缓冲区,512,1,填充);
//检查块是否是jpeg的开始
如果(缓冲区[0]==0xff&&buffer[1]==0xd8&&buffer[2]==0xff&&buffer[3]&0xf0)==0xe0)
{
//如果已打开,请关闭上一个文件
如果(输出文件!=NULL)
{
fclose(输出文件);
}
//克里特新出口
sprintf(文件名为“%03i.jpg”,n);
outfile=fopen(文件名,“w”);
//将块写入输出文件
fwrite(缓冲区,512,1,输出文件);
n++;
}
其他的
{
//将块写入当前输出文件
如果(输出文件!=NULL)
{
fwrite(缓冲区,512,1,输出文件);
}
}
}
//关闭最后一个输出文件
fclose(输出文件);
//封闭填充
fclose(infle);
}

我发现了几个可能导致该问题的因素

首先,检查
n
计数器的顺序。在您实际开始编写新文件之前,应该添加计数器,但这只是一个偏好问题,以及您希望代码有多干净

其次,尝试用以下代码替换您的
else
条件:

if(outfile != NULL)                          
      {
        fwrite(buffer, 512, 1, outfile);
}
注意:请记住,我已将您的
else
条件替换为
if
条件。这是因为当满足第一个
条件时,如果满足了
条件,则执行该条件并“跳出块”。因此,如果
条件不执行,
else
将只执行第一个
。
如果您想保持
else
状态,那么您应该像在代码中那样嵌套另一个
If

通过将
else
替换为
if
,无论jpg的前3个字节的值是多少(也就是说,无论它们是0x00、0xff、0x00),您都会得到一个非常清晰易懂的代码

最后,也是更重要的一点:为什么要在同一个操作中向同一个文件写入两次?请注意
n++
计数器下面的
fwrite()
函数。真的有必要吗

换句话说:删除此行:

//读取一个块
fread(缓冲区,512,1,填充)

另一个错误是,您正在读取文件两次,并且在每一步中前进两次,所以您将获得一半的信息。 这就是为什么你会得到一半的图片(27张左右)

删除这两行:

//读取一个块
fread(缓冲区,512,1,填充)

正如我所说,通过在文件中读写两次,您可以获得一半的信息。这就导致了一种模糊的方式,在这种方式下,你可以让你的图像全部用无意义的颜色(我猜)和一半的图像文件着色

我已经用您的代码和我刚才提供给您的固定解决方案运行了
check50 2016.recover.c
,它通过了CS50 check50的所有检查。花点时间考虑一下程序中的所有内容,包括控制流(它是程序的一个重要部分),以及指针的用法


在没有任何经验的情况下启动CS50可能会让人望而生畏。坚持下去。你已经快进入第五周了

您的
文件名
太短(空终止?)。花了好几个小时在上面……嗯,有点浪费。@Eugene,根据规范,文件名应该是XXX.jpg。考虑到空终止,我想我需要8个字符来存储文件名。还是我遗漏了一些明显的东西?(我以0之前的经验开始cs50:)@Mark,您可以在此处找到我的输出示例:。我不知道输出应该是什么样子,但它应该是一幅清晰的图片。我错了,对不起。错算了角色。谢谢大家!这真的很有帮助。我没有意识到while循环条件中的fread也提升了指针。更改了我的代码并通过了检查50。到第5周!:D