【发布时间】:2015-09-01 16:53:31
【问题描述】:
我正在为一个类构建一个程序,该程序以 512 字节的块从原始文件中提取所有字节,在每个块的开始字节中搜索 JPG 签名,并在找到 JPG 签名后写出 JPG 图像。我已经成功地从原始文件中提取了一个 JPG,但是课程表明还有更多。在 GDB 中调试后,我注意到变量“jpgname”似乎从来没有值,而且,单步执行程序时,我经常跳到“fclose(inptr)”行,就好像它在 main 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
}
【问题讨论】:
-
表达式:
sizeof(char)被定义为 1,并且对发送到 malloc() 的值绝对没有影响。建议通过删除该表达式来整理代码。始终检查 (!=NULL) malloc() 的返回值以确保操作成功 -
这一行:
printf("Could not open file\n");不是处理从系统函数返回的错误的好方法。而是使用perror( "some text" );,因为 perror 将输出“一些文本”和系统错误消息,这些信息将由“errno”变量选择。 -
调用
fread()紧跟while( fread() )意味着文件中的第一个JPG 将丢失 -
在调用系统函数
fopen()时,始终检查(!=NULL)返回值以确保操作成功 -
是什么让您认为 jpg 文件将是 512 字节的精确倍数?建议遵循此页面中的详细信息:stackoverflow.com/questions/2517854/…>,因为它具有指向适当库的链接、jpeg 文件布局的讨论等。