我无法理解如何使用char数组(std :: ifstream.read()的第一个参数来比较不同类型的数据)。
例如,如果我试图阅读Windows PE文件的魔力,我这样做但我觉得有更好的方法围绕它,因为据我所知,这需要我定义每个预先假设的值file作为std :: array:
std::array<char, 2> magic;
in.read(magic.data(), magic.size());
std::array<char, 2> shouldBe = { 0x4d, 0x5a }; // MZ for dos header
if(magic == shouldBe) {
// magic correct
}
这给了我编译器警告,例如从int到char的无效转换。 我也不太清楚我是如何读取其他十六进制值与ASCII字符完全相关的文件的神奇之处。 例如,每个Java类文件都以0xCAFEBABE开头是一个神奇的但是当我以4个字符读取它然后将每个部分转换为int时,我得到了我不想要的填充。
char* magic = new char[4];
in.read(magic, 4);
// how can I compare this array to 0xCAFEBABE?
当我遍历每个部分然后转换为int并在输出流中使用std :: hex时输出:
ffffffca fffffffe ffffffba ffffffbe
解析PE文件和Java类等二进制文件格式中使用的大量不同类型值的最佳方法是什么?
答案 0 :(得分:3)
这种方法非常好。唯一的问题是这一行:
std::array<char, 2> shouldBe = { 0x4d, 0x5a }; // MZ for dos header
列表初始化不允许缩小转换,因此您只需要进行一些显式转换:
std::array<char, 2> shouldBe = { (char)0x4d, (char)0x5a };
答案 1 :(得分:1)
您基本上有两种选择:您可以将值硬编码到程序中,也可以将它们存储在外部。如果你在内部存储它们,那么通过稍微构建数据可能最容易开始:
struct magic {
std::string value;
int result;
};
std::vector<magic> values {
{ ".ELF", 1 },
{ "MZ", 2},
{ "\xca\xfe\xba\xbe", 3}, // 0xcafebabe
{ "etc", -1}};
然后你可以(例如)在循环中逐步执行值,比较值,当你得到匹配时有一个值告诉你(例如)如何处理那种文件。
如果您将值存储为我在此处所做的字符串,那么将字符串进行比较可能也是最简单的。一种显而易见的方法是从文件的开头读取一个块(例如,2千字节),然后从文件中的正确字节数创建一个字符串,然后与预期值进行比较。