我正在为一个类构建一个程序,该类以512字节为单位从原始文件中提取所有字节,在每个块的开头字节中搜索JPG签名,并在找到JPG签名时写出JPG图像。我已经成功从原始文件中提取了一个JPG,但是该课程表明还有更多。在GDB中调试之后,我注意到变量“jpgname”似乎从来没有一个值,而且,通过程序,我经常步入“fclose(inptr)”行,就像它在主要内部一样while()循环。我错误地使用GDB吗?我是否正确使用sprintf()?我将不胜感激任何关于这个问题的反馈。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
typedef uint8_t BYTE;
int main(void)
{
BYTE jpg1[4] = {0xff, 0xd8, 0xff, 0xe0};
BYTE jpg2[4] = {0xff, 0xd8, 0xff, 0xe1};
int open = 0;
FILE* outp;
char* jpgname = malloc(sizeof(char) * 8);
int counter;
//TODO - MAKE sure this isn't a bunch of garbage data
//open card file
FILE* inptr = fopen("card.raw", "r");
if (inptr == NULL)
{
printf("Could not open file\n");
return 2;
}
BYTE buffer[512];
fread(buffer, 512, 1, inptr);
//repeat until end of card
while(fread(buffer, 512, 1, inptr) > 0)
{
counter = 0;
//start of new jpg?
if((buffer[0] == jpg1[0] && buffer[1] == jpg1[1] && buffer[2] == jpg1[2] && buffer[3] == jpg1[3]) || (buffer[0] == jpg2[0] && buffer[1] == jpg2[1] && buffer[2] == jpg2[2] && buffer[3] == jpg2[3]))
{
sprintf(jpgname, "%d.jpg", counter);
if (open == 1)
{
//close
fclose(outp);
//name new file
outp = fopen(jpgname, "w");
//write new
fwrite(buffer, sizeof(buffer), 1, outp);
counter++;
}
else if (open == 0)
{
//write new file
outp = fopen(jpgname, "w");
fwrite(buffer, sizeof(buffer), 1, outp);
open = 1;
counter++;
}
}
else
{
if(open == 1)
{
fwrite(buffer, sizeof(buffer), 1, outp);
}
}
}
fclose(outp);
fclose(inptr);
//close any remaining files
}
答案 0 :(得分:1)
BYTE buffer[512];
fread(buffer, 512, 1, inptr);
//repeat until end of card
while(fread(buffer, 512, 1, inptr) > 0)
你应该检查为什么你决定放弃读入的开头512字节。
FILE* inptr = fopen("card.raw", "r");
您应该以二进制模式打开输入文件和输出文件,如:
FILE* inptr = fopen("card.raw", "rb");
outp = fopen(jpgname, "wb");
否则,读入或写出的数据可能会混乱。
答案 1 :(得分:0)
虽然我很欣赏每个人的输入并使我的代码更好,但导致程序根本无法工作的错误是由于我的计数器在循环开始时被重置为0。
while(fread(buffer, 512, 1, inptr) > 0)
{
counter = 0;
...
}
应该是
counter = 0;
while(fread(buffer, 512, 1, inptr) > 0)
{
...
}