【问题标题】:C program not terminating [closed]C程序未终止[关闭]
【发布时间】:2017-09-22 13:33:11
【问题描述】:

我使用 c 编程来获取存储卡上删除的 jpeg 数据(由文件 card.raw 表示)。我现在正在尝试恢复这些 jpeg 文件。 问题:我的代码编译但它不会终止。 我想到了while循环的另一个条件,但不幸的是我不知道如何正确地做。 (试过EOF和feof)

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

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

// open input file
FILE *inptr = fopen(argv[1], "r");
//error if unable to open
if (inptr == NULL)
{
    fprintf(stderr, "Could not open %s.\n", argv[1]);
    return 2;
}

//variables
char buffer[512] = {0};
char jpeg1[4] = {0xff, 0xd8, 0xff, 0xe0};
char jpeg2[4] = {0xff, 0xd8, 0xff, 0xe1};
int count = 0;
char name[8] = {0};
FILE *outfile;
int isopen = 0;

//do while end of file is not reached
while (fread(buffer,1, 512, inptr) > 0)
{
    //compare buffer to bytes
    if (memcmp(buffer, jpeg1,4) == 0    || memcmp(buffer, jpeg2,4) == 0)

    {
        //close old outfile if open
        if(isopen ==1)
        {
            fclose(outfile);
        }

        //name for next outfile
        count ++;
        sprintf(name, "%03d.jpg", count);

        //open outfile and catch errors
        outfile = fopen(name, "w");
        if (outfile == NULL)
        {
            printf("Error opening outfile.\n");
            return 3;
        }
        isopen = 1;

        // write the first 512 bytes
        fwrite(buffer, 1, 512, outfile);
    }
    //no new jpeg
    // if outfile is open
    if (isopen == 1)
    {
        fwrite(buffer, 1, 512, outfile);
    }

    //move reader of fread()
    fseek(inptr, 1, SEEK_SET);
}

//close files
fclose(inptr);
fclose(outfile);

// success
return 0;
}

【问题讨论】:

  • 你应该使用fread(...) &gt; 0而不是fread(...) == 512
  • 尽量避免在您的代码中使用幻数(例如512)。如果您在代码顶部使用#define NMEMB 512,它必须更容易(并且更容易维护)。如果您需要更改值,您可以在一个地方进行更改,而不必在代码中的每个 fread/fwrite 调用中进行选择以更改它 :) 当有人查看 @ 时也不足为奇987654329@,例如size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
  • 这是 CS50 课程的问题之一。阅读How to Ask,特别是关于作业问题的部分。
  • 注意:使用fread(),最好以binary模式打开文件fopen(argv[1], "rb");
  • 提示:避免小气使用缓冲区。 char name[8] = {0}; ... sprintf(name, "%03d.jpg", count); 这是一个缓冲区溢出,count 超出范围 [-99...999]。为更广泛的计数做好准备。也许char name[21 /*64-bit int */ + 4 /* fmt */ + 1] = {0};。根据设计,您“知道”代码永远不需要超过 8 大小的缓冲区,但现在代码已经损坏,所以可能是一个大的 count 使问题更加复杂。

标签: c jpeg restore cs50


【解决方案1】:

你无限循环。

删除

fseek(inptr, 1, SEEK_SET);

每次执行循环时,将文件指针重置为文件的开头。


PS:尽量避免使用幻数,比如 512。我会改用 #define NMEMB 512 这样的定义。

【讨论】:

  • 当然问题只是 fseek 将读取指针重置为文件开头。 fread 如果没有读取完整的块,则可以返回少于 512 个字节,但这仍然需要处理。
  • 关于fread 的部分仍然关闭 - 如果它读取 511 个字节,您将退出循环并错过读入的最后一块数据。
  • 是的,现在看起来好多了:)
猜你喜欢
  • 2011-11-29
  • 1970-01-01
  • 2013-01-26
  • 2019-12-11
  • 1970-01-01
  • 2021-07-07
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多