C ++从文件中读取和比较幻数

时间:2016-06-14 21:45:48

标签: c++ file io binary magic-numbers

我有我希望用C ++阅读的文件。我必须阅读和检查的第一件事是文件的幻数。在我的例子中,它是十六进制值:0xABCDEF00

我通过这种方式阅读和比较数字:

ifstream input ("C:/Desktop/myfile", ios::binary);
if (input.is_open()) {
input.seekg(0, ios::beg);
unsigned char magic[4] = {0};
input.read((char*)magic, sizeof(magic));

if(magic[0] == 0xAB &&
   magic[1] == 0xCD &&
   magic[2] == 0xEF &&
   magic[3] == 0x00) {
   cout << "It's my File!" << endl;
} else {
   cout << "Unknown File!" << endl;
}
}

这非常有效,但是有没有办法比较整个read char [] - Array?像这样:

unsigned int magicNumber = 0xABCDEF00;
... same code for reading file as above ...
Instead of checking each Array-Entry a way like this: 

if(magic == magicNumber) {
    do something ...
}

很高兴知道是否有这样的方式 - 如果不是因为我觉得没有这样的方式:)

4 个答案:

答案 0 :(得分:3)

你可以这样做:

union magic_t {
    uint8_t bytes[4];
    uint32_t number;
};

然后如你原先想要的那样:

magic_t my_magic = {0xAB, 0xCD, 0xEF, 0};
magic_t file_magic;
input.read((char *) file_magic.bytes, sizeof(file_magic));
if ( file_magic.number == my_magic.number )...

并且你根本不需要关心endianess。

取决于字节序数,可能会有所不同,但这根本不重要,因为即使数字不是0xABCDEF00,也总是正确的字节序列。

或者,或者,我们可以选择使用演员(但我觉得这很丑陋)。

答案 1 :(得分:2)

好老memcmp可以在这里提供帮助。阅读unsigned char magic[4]后,您可以像以下一样进行比较:

const unsigned char magicref[4] = {0xAB, 0xCD, 0xEF, 0}
if (memcmp(magic, magicref, sizeof(magic)) == 0) {
    // do something ...
}

这是独立的字节顺序。

如果您知道平台会为您提供神奇的数字并且不关心其他平台的可移植性,您可以直接处理所有内容uint32_t

uint32_t magic, refmagic = 0xABCDEF00;  // big endian here...
input.read(reinterpret_cast<char *>(&magic), sizeof(magic)); // directly load bytes into uint32_t
if (magic == refmagic) {
    //do something...
}

这在不同平台上不可移植,但可以在简单的情况下使用,只要用粗体红色闪烁字体表示请注意:仅在大端系统上使用

答案 2 :(得分:1)

如果您知道平台的endiannes,则可以使用uint32_t变量来执行此操作。

对于小端系统,请使用:

unit32_t number;
input.read(reinpterpret_cast<char*>(&number), 4);
if ( number == 0x00EFCDAB )
{
   cout << "It's my File!" << endl;
}

对于大端系统,请使用:

unit32_t number;
input.read(reinpterpret_cast<char*>(&number), 4);
if ( number == 0xABCDEF00 )
{
   cout << "It's my File!" << endl;
}

答案 3 :(得分:1)

这里已经有很好的答案!对于记录,此处使用标准<algorithm>库的equal()变体:

unsigned char magic[4] = {0};
input.read((char*)magic, sizeof(magic));

const unsigned char code[4] = { 0xab, 0xcd, 0xef, 0x00 };
if(equal(code, code+sizeof(code), magic)) 
    cout << "It's my File!" << endl;
else 
   cout << "Unknown File!" << endl;

它与memcmp()版本非常相似,但它适用于任何容器,而不仅仅是char数组。

Online demo