у меня есть файл, который я хочу читать на 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;
}
}
Это работает очень хорошо, но есть ли способ сравнить весь прочитанный символ [] — Массив сразу? Вот так:
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 ...
}
Было бы неплохо узнать, есть ли такой способ — если не спасибо, что сказал мне, что такого пути нет 🙂
Старый добрый 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...
}
Это не переносится на разные платформы, но может использоваться в простых случаях, если комментарий выделен жирным красным мигающим шрифтом, говоря ВНИМАНИЕ: использовать только в системе с прямым порядком байтов
Ты можешь сделать:
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 )...
и вам не нужно заботиться о порядке байтов
В зависимости от порядкового номера число может быть разным, но это не имеет значения, так как это всегда будет правильная последовательность байтов, даже если число не равно 0xABCDEF00.
Или, по желанию, мы можем просто использовать кастинг (но я думаю, что это некрасиво).
Здесь уже есть очень хорошие ответы! Для записей, здесь вариант с использованием equal()
стандарта <algorithm>
библиотека:
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.
Если вы знаете порядковый номер вашей платформы, вы можете использовать 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;
}