我需要检查文件是 .doc
、.ppt
、.pdf
还是任何其他文件。我写了下面的代码:
bool CheckFile(string path)
{
char * sig;
sig = new char[8];
ifstream myfile;
myfile.open(path.c_str(), ios::in | ios::binary);
if (myfile.fail())
{
MessageBox(0,"File Not Opened","ERROR",MB_OK);
break;
}
myfile.read(sig,8);
//docx, pptx, xlsx
if ((sig[0] == (0x50))&&(sig[1] == (0x4B))&&(sig[2] == (0x03))&&(sig[3] == (0x04))&&(sig[4] == (0x14))&&(sig[5] == (0x00))&&(sig[6] == (0x06))&&(sig[7] == (0x00)))
{
return true;
}
//doc, ppt, xls
if ((sig[0] == (0xD0))&&(sig[1] == (0xCF))&&(sig[2] == (0x11))&&(sig[3] == (0xE0))&&(sig[4] == (0xA1))&&(sig[5] == (0xB1))&&(sig[6] == (0x1A))&&(sig[7] == (0xE1)))
{
return true;
}
//pdf
if ((sig[0] == (0x25))&&(sig[1] == (0x50))&&(sig[2] == (0x44))&&(sig[3] == (0x46)))
{
return true;
}
delete sig;
myfile.close();
return false;
}
我在互联网上查找,发现我们可以比较签名,即 MS office 文件的前 8 个字节和 PDF
的前 4 个字节。在上面的代码中,我也在做同样的事情。 CheckFile()
在 PDF
和 Office 2007 格式(包括 .docx
和 .pptx)的情况下返回
但在 TRUE
.doc
和 .ppt
的情况下返回 FALSE
。 .doc
文件的控制台输出为:
FFFFFFD0
FFFFFFCF
11
FFFFFFE0
FFFFFFA1
FFFFFFB1
1A
FFFFFFE1
其中每行对应于 sig 中 char 的十六进制。请注意,最后一个字节与 .doc
文件的签名相同。我不知道为什么这些额外的 FFFFFF
会出现在这里。可能是什么问题??
最佳答案
关于 FFFFFFFF
的问题,您可能会注意到这些数字的最后一个字节大于 0x7f
,这意味着它们对于带符号的字节是负数。因此,您使用的是带符号的 char
并且编译器在您打印值时对其进行符号扩展。
您应该更改为 unsigned char
(或者更好,标准类型 uint8_t
)。
关于c++ - 通过比较签名无法识别 MS Office 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16815599/