Я пытаюсь прочитать / распечатать шестнадцатеричные инструкции из версии Pong для Chip8 (которую можно скачать Вот).
Вот код, который я использую для чтения в ПЗУ:
//Open ROM
string dir = "Test/PONG";
ifstream inf(dir.c_str(), ios::binary);
unsigned char input;
for(int i = 0; inf >> input; i++) {
//Each loop prints 1 bytes
//New line every 16 bytes and print line number
if(i%16 == 0) {
cout << endl;
cout << setw(7) << setfill('0') << i << " ";
}
//2 extra spaces after 8 bytes
else if(i%8 == 0)
cout << " ";
cout << hex << setw(2) << setfill('0') << (int)input << " ";
}
cout << endl;
И вот часть вывода:
0000000 6a 02 6b 6c 3f 6d a2 ea da b6 dc d6 6e 00 22 d4
0000010 66 03 68 02 60 60 f0 15 f0 07 30 00 12 1a c7 17
0000020 77 08 69 ff a2 f0 d6 71 a2 ea da b6 dc d6 60 01
…
И вот вывод, который я считаю правильным, который я получил, выполнив команду «hexdump -C PONG» в терминале:
00000000 6a 02 6b 0c 6c 3f 6d 0c a2 ea da b6 dc d6 6e 00
00000010 22 d4 66 03 68 02 60 60 f0 15 f0 07 30 00 12 1a
00000020 c7 17 77 08 69 ff a2 f0 d6 71 a2 ea da b6 dc d6
…
В первой строке шестнадцатеричных значений вы можете видеть значение «0c» дважды в терминале, но вывод кода пропускает вывод «0c». Я не уверен, почему мой код пропускает ‘0c’. Я неправильно читаю файл? Команда «hexdump» предоставляет неправильный вывод? Что я могу изменить в том, как я читаю файл?
РЕДАКТИРОВАТЬ: Использование inf.get (input) может читать в ‘0c’, но также выводит некоторые шестнадцатеричные значения по-разному.
Например:
6a 02 6b 0c 6c 3f 6d 0c ffffffa2 ffffffea ffffffda ffffffb6 ffffffdc ffffffd6 6e 00 22 ffffffd4 66 03 68 02 60 60 fffffff0
РЕДАКТИРОВАТЬ 2: ‘F’ печатаются, так как некоторые шестнадцатеричные значения читаются как отрицательные числа. Поэтому я сделал оператор if, который проверяет, является ли вход отрицательным, если он отрицательный, я умножаю его на -1, а затем печатаю шестнадцатеричное значение.
РЕДАКТИРОВАТЬ 3: Я решил использовать поток строк, чтобы распечатать только 2 последних символа для отрицательных шестнадцатеричных значений:
stringstream convert;
if((int)input < 0) {
convert << hex << (int)input;
cout << convert.str().substr(6,8) << " ";
convert.str("");
}
РЕДАКТИРОВАТЬ 4: шестнадцатеричный ‘0c’ представляет escape-последовательность ‘\ f’ и поэтому игнорируется при печати. С помощью inf.get(input)
вместо inf >> input
сохраняет символы на входе как неформатированные символы (я думаю). Тем не менее get()
функция не может взять unsigned char
в качестве аргумента. Поэтому я должен бросить char&
,
В заключение я должен был изменить inf >> input
в inf.get((char&)input)
,
Источник: http://www.cplusplus.com/reference/istream/istream/get/
Оператор >> читает отформатированные данные (char в вашем случае) из входного потока, поэтому char со значением 12 (0c в шестнадцатеричном формате) рассматривается как подача формы ASCII и игнорируется (так как значение 32 или 0x20 будет считаться пробелом) ,
Char также являются знаковыми значениями, и шестнадцатеричное значение a2 (которое является десятичным 162) будет сохранено как отрицательное значение. Повышение этого значения до int сохранит знак, и из-за дополнения, когда вы напечатаете как unsigned, вы получите ffff’s.
держать
unsigned char input;
Затем, чтобы прочитать значения использовать
inf.get(static_cast<char>(input))
и распечатать
cout << hex << setw(2) << setfill('0') << static_cast<unsigned int>(input) << " ";
Ты используешь (signed) int
как ваша переменная. Когда signed int
отрицательный и напечатан в шестнадцатеричном виде, ему будет предшествовать один или несколько F
цифры.
Я настоятельно рекомендую использовать unsigned int
для ваших ценностей.