【发布时间】:2015-12-15 18:59:02
【问题描述】:
我不知道如何使用 char 数组(std::ifstream.read() 的第一个参数来比较不同类型的数据)。
例如,如果我试图读取 Windows PE 文件的魔力,我正在这样做,但我觉得有更好的方法来解决它,因为据我所知,这需要我在文件作为 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 字符完全不相关的其他文件的。 例如,每个以 0xCAFEBABE 开头的 Java 类文件都很神奇,但是当我将其读取为 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 类)的大量不同类型值的最佳方法是什么?
【问题讨论】:
-
首先,不要使用
char,因为它可能是signed或其他。使用uint8_t,这是一个无符号的 8 位数量。您可以将其转换为read()参数内的char类型:in.read((char *) magic, 4); -
嗯?什么编译器警告?哪条线?
-
@Barry 我收到一个警告:
std::array<char, 4> magic; inClass.read(magic.data(), 4); std::array<char, 4> classMagic = { 0xCA, 0xFE, 0xBA, 0xBE };警告:在 { } [-Wnarrowing] std::arrayclassMagic = { 0xCA, 0xFE, 0xBA, 0xBE }; ^ -
@user3530525:左边没有填充。在这种情况下,char 似乎是有符号的,因此每个大于 0x7F (=127) 的值都会溢出为负值。当将负值转换为 int 时,它应该保持负数,因此您可以将它们读取为例如 0xffffffca,它与 char 0xca,-56 具有相同的值。