将数组元素与常量比较时出错 C

5

我正在用C语言编写一个程序,试图恢复任何被删除的JPG文件。

我的总体方法是将文件的块大小(在FAT上为512个字节)加载到内存中,以查看前四个字节中是否存在JPG签名(保证在这些字节中存在)。

如果存在签名,则我将继续将512字节的数据块写入文件,直到看到另一个JPG文件等。

以下是目前的代码:

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

#include "jpg.h" /*set uint8_t to  BYTE */  

int main(int argc, char* argv[])
{
    // Opens the rFile
    FILE* rFile = fopen("card.raw", "r");

    // Checks for errors in opening rFile and terminates program
    if (rFile == NULL)
    {
        printf("Error opening rFile");
        return 0;
    }

    // Sets the blocksize (depends on the filesystem)
    int blockSize = 512;

    // allocates space for buffer on heap
    char* buf = malloc(blockSize);

    // image counter
    int icount = 0;

    // write file
    FILE* wFile = NULL; 

    // iterates through content of rFile in size buf
    while (fread(&buf, blockSize, 1, rFile))
    {

        // Check if the first four bytes are JPG signature
        if (buf[0] == 0xff && buf[1] == 0xd8 && buf[2] == 0xff
            && (buf[3] == 0xe0 || buf[3] == 0xe1))
        {
            // Close the file, if opened
            if (wFile != NULL)
                fclose(wFile);

            // Determine name of new file
            char filename[8];
            sprintf(filename, "%03d.jpg", icount);

            // Open new JPG for Writing
            wFile = fopen(filename, "w");

            // Iterates the filename icount
            icount++; 
        }

        // Write blocksize to file
        if (wFile != NULL)
            fwrite(buf, blockSize, 1, wFile);
    }

    // Close the current file if exists 
    if (wFile != NULL)
        fclose(wFile);

    // Frees buffer on heap
    free(buf);

    // Close read file
    fclose (rFile);

}

然而,在编译时,编译器会提示无法将buf[0-3]与常量进行比较,这些常量是JPG的签名字节。
if (buf[0] == 0xff && buf[1] == 0xd8 && buf[2] == 0xff && (buf[3] == 0xe0 || buf[3] == 0xe1))
{
    doStuff();
{

我得到的错误是:
clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wshadow    recover.c  -lcs50 -lm -o recover
recover.c:44:20: error: comparison of constant 255 with expression of type 'char' is always false [-Werror,-Wtautological-constant-out-of-range-compare]
        if (buf[0] == 0xff && buf[1] == 0xd8 && buf[2] == 0xff
            ~~~~~~ ^  ~~~~
recover.c:44:38: error: comparison of constant 216 with expression of type 'char' is always false [-Werror,-Wtautological-constant-out-of-range-compare]
        if (buf[0] == 0xff && buf[1] == 0xd8 && buf[2] == 0xff
                              ~~~~~~ ^  ~~~~
recover.c:44:56: error: comparison of constant 255 with expression of type 'char' is always false [-Werror,-Wtautological-constant-out-of-range-compare]
        if (buf[0] == 0xff && buf[1] == 0xd8 && buf[2] == 0xff
                                                ~~~~~~ ^  ~~~~
recover.c:45:24: error: comparison of constant 224 with expression of type 'char' is always false [-Werror,-Wtautological-constant-out-of-range-compare]
            && (buf[3] == 0xe0 || buf[3] == 0xe1))
                ~~~~~~ ^  ~~~~
recover.c:45:42: error: comparison of constant 225 with expression of type 'char' is always false [-Werror,-Wtautological-constant-out-of-range-compare]
            && (buf[3] == 0xe0 || buf[3] == 0xe1))
                                  ~~~~~~ ^  ~~~~
5 errors generated.
make: *** [recover] Error 1

编辑:

感谢您的帮助,现在它可以工作了。(我将缓冲区更改为unsigned char并使用fread(buf...)而不是fread(&buf...)。)

所有这些帮助引发了一些新问题,如果有任何大牛有时间回答它们,我会非常感激。

  • 正如Quentin和WhozCraig建议的那样,将char* buf更改为unsigned char* buf-为什么无符号情况下它能够工作?
  • 正如MM建议的那样,使用fread(&buf而不是fread(buf进行读取时为什么会导致分段错误,&buf不应指向相同的内存吗?
  • 正如MM再次建议的那样,为什么和如何使sprintf缓冲区溢出,以及“使用snprintf或模数运算符将操作数限制在0到999之间。或增加缓冲区大小”是什么意思?

我知道这些可能是愚蠢的问题,但对我来说仍然很有价值。


4
您现在可以假设您的平台上的 char 是有符号的。我建议将 buf 更改为 unsigned char * - WhozCraig
1
fread(&buf 应该改为 fread(buf - M.M
1
sprintf可能会发生缓冲溢出;要么使用snprintf,或使用模运算符将操作数限制在0到999之间。要么增加缓冲区大小。 - M.M
哦,如果你在Windows上,我还会将读取模式更改为“rb”。 - WhozCraig
1个回答

9

char在你的平台上是有符号类型,而0xe0无法容纳在有符号的char中。
buf的类型改为unsigned char


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接