我无法弄清楚为什么架子无法正确填充我的缓冲区。 CS50恢复
我已经在GDB中撕下了此代码数小时。我知道fread
正在返回适当的字节数(512
)。甚至检查了$ eax
打印以确认。有人有可能有人暗示我的逻辑有什么问题吗?
我认为标题可能会从文件的开头偏移,因此我认为在第一次读取字节时,请查找hex匹配,并设置fseek
可以解决问题。没有这样的运气。打印匹配结果是0
。
#include <stdio.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
typedef enum { false, true } boolean;
int main(int argc, char *argv[])
{
// get filenames from cml input and open file
char *infile = argv[optind];
char *fileName = "image";
FILE *rawData = fopen(infile, "r");
FILE *imgJPG = fopen(fileName, "w");
int match = 0;
int imgCnt = 0;
// buffer to hold 512 bytes of file data - FAT file system
BYTE *FATbuffer = (BYTE *)malloc(sizeof(BYTE) * 512);
if (rawData == NULL)
{
printf("Error processing file. Exiting...");
return 1;
}
// begin reading raw data and writing it to buffer
while (fread(FATbuffer, sizeof(BYTE), 512, rawData) == 512)
{
if (imgCnt == 0)
{
for (int c = 0; c < 512; c++)
{
if (FATbuffer[c + 0] == 0xff &&
FATbuffer[c + 1] == 0x8d &&
FATbuffer[c + 2] == 0xff)
{
fseek(rawData, c, SEEK_SET);
imgCnt++;
match++;
}
}
}
else
{
if (FATbuffer[0] == 0xff &&
FATbuffer[1] == 0x8d &&
FATbuffer[2] == 0xff &&
imgCnt > 0)
{
sprintf(fileName, "%d.jpg", imgCnt);
fclose(imgJPG);
imgCnt++;
}
if (imgJPG == NULL)
{
printf("Error processing file. Exiting...");
return 3;
}
fwrite(FATbuffer, sizeof(BYTE), 512, imgJPG);
}
}
printf("%d\n", match);
// file processed, free memory
free(FATbuffer);
return 0;
}
I've torn through this code in gdb for hours. I know that fread
is returning the appropriate amount of bytes (512
). Even checked the $eax
print to confirm. Is there any chance someone may be able to give me a hint at what's wrong with my logic?
I thought that the headers may be offset from the beginning of the file, so I figured on first read going through byte by byte looking for the hex match and setting fseek
would do the trick. No such luck. Printing match results in a 0
.
#include <stdio.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
typedef enum { false, true } boolean;
int main(int argc, char *argv[])
{
// get filenames from cml input and open file
char *infile = argv[optind];
char *fileName = "image";
FILE *rawData = fopen(infile, "r");
FILE *imgJPG = fopen(fileName, "w");
int match = 0;
int imgCnt = 0;
// buffer to hold 512 bytes of file data - FAT file system
BYTE *FATbuffer = (BYTE *)malloc(sizeof(BYTE) * 512);
if (rawData == NULL)
{
printf("Error processing file. Exiting...");
return 1;
}
// begin reading raw data and writing it to buffer
while (fread(FATbuffer, sizeof(BYTE), 512, rawData) == 512)
{
if (imgCnt == 0)
{
for (int c = 0; c < 512; c++)
{
if (FATbuffer[c + 0] == 0xff &&
FATbuffer[c + 1] == 0x8d &&
FATbuffer[c + 2] == 0xff)
{
fseek(rawData, c, SEEK_SET);
imgCnt++;
match++;
}
}
}
else
{
if (FATbuffer[0] == 0xff &&
FATbuffer[1] == 0x8d &&
FATbuffer[2] == 0xff &&
imgCnt > 0)
{
sprintf(fileName, "%d.jpg", imgCnt);
fclose(imgJPG);
imgCnt++;
}
if (imgJPG == NULL)
{
printf("Error processing file. Exiting...");
return 3;
}
fwrite(FATbuffer, sizeof(BYTE), 512, imgJPG);
}
}
printf("%d\n", match);
// file processed, free memory
free(FATbuffer);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
代码中存在多个问题:
您应该测试是否有命令行参数(处理选项后,您可能要删除用于发布的代码)。
必须以二进制模式打开文件,以避免翻译的潜在末端。
您应该延迟打开
imgjpg
直到找到JPG标头。无需分配
fatbuffer
,定义具有自动存储的512字节数组是可以的。您一次扫描JPG签名一个块,但是如果它跨越512字节边界,您可能会错过签名,并且您可以在
fatbuffer
array时访问2个字节。 > c 大于509。fseek(rawdata,c,seek_set);
设置文件位置从数组开始的开头,而不是从文件的开头设置。<<<<<<<<<<<<<<<<<<< /p>sprintf(文件名,“%d.jpg”,imgcnt);
尝试覆盖字符串常数。这具有不确定的行为。您可能的意思是:这是一个修改版本,可以提取数据流中任何地方嵌入的JPG文件:
如果您可以假设签名处于扇区的开头,则可以简化代码:
There are multiple problems in your code:
you should test if a command line argument is available (after handling options, code you probably removed for posting).
files must be open in binary mode to avoid potential end of translation.
you should delay opening
imgJPG
until you have found the JPG header.there is no need to allocate
FATbuffer
, defining a 512 byte array with automatic storage is fine.you scan for the JPG signature one block at a time, but you might miss the signature if it spans a 512 byte boundary and you access 2 bytes beyond the end of the
FATbuffer
array whenc
is greater than 509.fseek(rawData, c, SEEK_SET);
set the file position at the offset from the beginning of the array, not from the beginning of the file.sprintf(fileName, "%d.jpg", imgCnt);
attempts to overwrite a string constant. This has undefined behavior. You probably meant this:Here is a modified version that can extract JPG files embedded anywhere in a data stream:
If you can assume the signature to be at the start of a sector, the code can be simplified: