2016-07-11 2 views
2

Я делаю программу на C, которая пытается восстановить любые удаленные JPG.Ошибка при сравнении элементов массива с константой C

Мой общий подход состоит в том, чтобы загрузить размер блока (по 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); 

} 

Однако при компиляции, компилятор говорит, что не может сравнить БУФ [0-3] для констант, которые являются подписи байта JPGs

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 

EDIT:

Спасибо за вашу помощь он работает сейчас. (Я изменил буфер на unsigned char и fread (buf ...) вместо fread (& buf ...).

Вся эта помощь дала начало нескольким новым вопросам, если у любого гуру есть время ответить на них я был бы благодарен

  • Как Квентин и WhozCraig предложил, изменив символ * БУФ в беззнаковое символ * BUF. - почему это работает, когда это беззнаковое
  • Как было предложено М.М. почему? он дает ошибку сегментации, используя fread (& buf вместо fread (buf при чтении, не должен & Buf должен указывать на ту же память?
  • Поскольку MM снова предложила, почему и как происходит переполнение буфера sprintf, и что именно «использует snprintf или оператор модуля для ограничения операнда между 0 и 999. или увеличение размера буфера»?

Я знаю, что это, вероятно, глупый вопрос, но тем не менее ценный для меня.

+4

Теперь вы можете предположить, что 'char' * подписан * на вашей платформе. Я бы изменил 'buf' на' unsigned char * ' – WhozCraig

+1

' fread (& buf' должно быть 'fread (buf' –

+1

' sprintf' может переполнение буфера, либо использовать 'snprintf', либо оператор модуля для ограничения операнда от 0 до 999. или увеличить размер буфера –

ответ

5

char подписан на вашей платформе, а 0xe0 не вписывается в подписанный char.
Изменить buf 's type to unsigned char.

Смежные вопросы