Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.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
在C中未遇到文件结尾(eof)_C_Eof_Cs50 - Fatal编程技术网

在C中未遇到文件结尾(eof)

在C中未遇到文件结尾(eof),c,eof,cs50,C,Eof,Cs50,我正在尝试运行代码。除最后一张图像外,所有图像均符合规范要求 重复的前四个字节(B)如下所示: b8 97 98 c5 没有遇到文件结尾,因此发现最后一个图像已损坏 编辑: 已经提到文件中有50个图像 您可以从以下位置获取原始文件: 原代码如下: // Recovers lost images (.jpeg) in a memory card #include <stdio.h> #include <stdlib.h> #define buffsize 10 //

我正在尝试运行代码。除最后一张图像外,所有图像均符合规范要求

重复的前四个字节(B)如下所示:

b8 97 98 c5
没有遇到文件结尾,因此发现最后一个图像已损坏

编辑:

  • 已经提到文件中有50个图像
  • 您可以从以下位置获取原始文件:
  • 原代码如下:

    // Recovers lost images (.jpeg) in a memory card
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #define buffsize 10
    
    // Function to check whether jpeg or not
    int check_jpeg(unsigned char *argv) {
        unsigned int v1 = (int)argv[0];
        unsigned int v2 = (int)argv[1];
        unsigned int v3 = (int)argv[2];
        unsigned int v4 = (int)argv[3];
        if (v1 == 0xff && v2 == 0xd8 && v3 == 0xff) {
            switch (v4) {
              case 0xe0:
              case 0xe1:
              case 0xe2:
              case 0xe3:
              case 0xe4:
              case 0xe5:
              case 0xe6:
              case 0xe7:
              case 0xe9:
              case 0xea:
              case 0xeb:
              case 0xec:
              case 0xed:
              case 0xee:
              case 0xef:
                return 1;
                break;
              default:
                return 0;
            }
        } else {
            return 0;
        }
    }
    
    int main(int argc, char *argv[]) {
        // Cautioning the user for wrong usage
        if (argc != 2) {
            fprintf(stderr, "Usage: ./recover file\n");
            return 1;
        }
    
        // Opens the .raw file to begin inspection
        FILE *camera = fopen(argv[1], "r");
    
        // Checks the validity of the opened file
        if (camera == NULL) {
            fprintf(stderr, "Error opening file: %s\n",argv[1]);
            return 2;
        }
    
        int counter = 0; // Declaring and Initialising the counter
        int online = 0; // To know whether image is being written
    
        char *filename = (char*)malloc(buffsize);
        FILE *outptr;
    
        while (1) {
            unsigned char *image = malloc(512);
            if (image == NULL) {
                fprintf(stderr, "Error creating pointer \n");
                return 200;
            }
            fread(image, 512, 1, camera);
            if (image != NULL) {
                int flag = check_jpeg(image);
                if (counter == 50) {
                    printf("%x %x %x %x\n", image[0], image[1], image[2], image[3]);
                }
                if (flag == 1) {
                    if (counter != 0) {
                        fclose(outptr);
                    }
                    counter++;
    
                    // Creating the output file pointer
                    snprintf(filename, buffsize - 1, "%03i.jpg", counter);
                    outptr = fopen(filename, "w");
                    if (outptr == NULL) {
                        fprintf(stderr, "Error opening file: %s\n", filename);
                        return 201;
                    }
    
                    // Writing to the file
                    fwrite(image, 512, 1, outptr);
                    online = 1;
                } else
                if (flag == 0 && online == 1) {
                    fwrite(image, 512, 1, outptr); // Continue writing to the output file
                }
                free(image);
            } else {
                fclose(camera);
                fclose(outptr);
                return 0;
            }
        }
    }
    
    //恢复存储卡中丢失的图像(.jpeg)
    #包括
    #包括
    #定义大小10
    //用于检查是否为jpeg格式的函数
    int check_jpeg(无符号字符*argv){
    无符号int v1=(int)argv[0];
    无符号整数v2=(整数)argv[1];
    无符号int v3=(int)argv[2];
    无符号int v4=(int)argv[3];
    如果(v1==0xff&&v2==0xd8&&v3==0xff){
    交换机(v4){
    案例0xe0:
    案例0xe1:
    案例0xe2:
    案例0xe3:
    案例0xe4:
    案例0xe5:
    案例0xe6:
    案例0xe7:
    案例0xe9:
    案例0xea:
    案例0xeb:
    案例0xec:
    案例0xed:
    案例0xee:
    案例0xef:
    返回1;
    打破
    违约:
    返回0;
    }
    }否则{
    返回0;
    }
    }
    int main(int argc,char*argv[]){
    //警告用户错误使用
    如果(argc!=2){
    fprintf(stderr,“用法:./recover file\n”);
    返回1;
    }
    //打开.raw文件以开始检查
    文件*camera=fopen(argv[1],“r”);
    //检查打开的文件的有效性
    如果(摄像机==NULL){
    fprintf(stderr,“打开文件时出错:%s\n”,argv[1]);
    返回2;
    }
    int counter=0;//声明并初始化计数器
    int online=0;//了解是否正在写入映像
    char*filename=(char*)malloc(buffsize);
    文件*outptr;
    而(1){
    无符号字符*image=malloc(512);
    if(image==NULL){
    fprintf(stderr,“创建指针时出错\n”);
    返回200;
    }
    fread(图像,512,1,摄像机);
    如果(图像!=NULL){
    int flag=检查jpeg(图像);
    如果(计数器==50){
    printf(“%x%x%x%x\n”,图像[0],图像[1],图像[2],图像[3]);
    }
    如果(标志==1){
    如果(计数器!=0){
    fclose(outptr);
    }
    计数器++;
    //创建输出文件指针
    snprintf(文件名,buffsize-1,“%03i.jpg”,计数器);
    outptr=fopen(文件名,“w”);
    if(outptr==NULL){
    fprintf(stderr,“打开文件时出错:%s\n”,文件名);
    返回201;
    }
    //写入文件
    fwrite(图像,512,1,outptr);
    在线=1;
    }否则
    如果(标志==0&&online==1){
    fwrite(image,512,1,outptr);//继续写入输出文件
    }
    免费(图像);
    }否则{
    fclose(摄像机);
    fclose(outptr);
    返回0;
    }
    }
    }
    
    在读取失败时不会将指针(或至少不保证)设置为NULL。事实上,我认为应该保持指针不变<但是,code>fread将返回读取的字节数,因此您可以更改:

       fread(image, 512, 1, camera);
       if (image != NULL)
    


    您的代码中存在多个问题:

    • 您不检查有多少数据
      fread
      成功读取。在文件末尾,
      fread
      返回
      0
      ,否则
      fread
      返回成功读入目标数组的块数。要跟踪读取的字节,请将
      1
      作为块大小传递,将
      512
      作为块数传递
    • 实际上不需要分配文件名和输入/输出缓冲区,本地数组可以满足您的需要
    • 文件应以二进制模式打开:
      FILE*camera=fopen(argv[1],“rb”)
    • snprintf
      的第二个参数应该是缓冲区大小,而不是要写入的最大字符数:
      snprintf(文件名,buffsize,“%03i.jpg”,计数器)

    您可能会尝试执行以下操作:

    while (!feof(camera)) {
    
    但是,这仅在读取文件时没有其他错误的情况下有效,即使这样,也始终会导致额外读取一次文件(触发EOF条件的读取)。最后一次读取可能返回坏数据或指向陈旧数据,因此需要按照@chqrlie的答案和进行处理

    底线:
    检查读取的字节数,如果小于请求的字节数,则使用
    ferror()
    feof()
    来找出原因,以便您可以相应地作出响应。

    我在该代码中没有看到任何检查
    eof
    。检查
    fread()
    的返回值。我认为没有必要动态分配
    image
    。它也可以是一个数组。你从不检查什么东西,也不会返回。这是非常重要的,因为两者都可能失败,特别是检查
    fread
    返回的内容,因为它会告诉您是否已到达文件结尾。此外,我非常确定关于您的问题的时间会短得多。我甚至没有检查代码,我只是观察到raw和jpeg的格式有很大的不同。@visibleman这是一个编码任务,我猜“raw”文件应该是删除图像后的一些假设磁盘内容,您的工作是检测和恢复这些内容。-无论如何,对于a,您需要创建一个简单的示例程序,其中只包含所讨论的问题(因此图像在这里是无关的)。应该交换
    fread
    的参数:
    int-bytesread=fread(图像,1512,照相机)
    @Pritthijit Nath,我后来才看到它,但是的,您建议的编辑也会起作用。不,这是incor
    while (!feof(camera)) {