我正在用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之间。或增加缓冲区大小”是什么意思?
我知道这些可能是愚蠢的问题,但对我来说仍然很有价值。
char
是有符号的。我建议将buf
更改为unsigned char *
。 - WhozCraigfread(&buf
应该改为fread(buf
。 - M.Msprintf
可能会发生缓冲溢出;要么使用snprintf
,或使用模运算符将操作数限制在0到999之间。要么增加缓冲区大小。 - M.M