По сути, мне нужно написать утилиту шестнадцатеричного дампа с использованием C ++. Это будет выглядеть примерно так
(Часть шестнадцатеричного дампа документа Word с использованием Visual Studio)
Я хочу запросить у пользователя имя файла, а затем отобразить шестнадцатеричные значения, а также переведенные символы ASCII. Я все еще новичок в работе с бинарными файлами, поэтому, если бы вы могли сделать это простым, это было бы очень ценно.
Обычно я не делаю этого для твоего рода вопросов … Но не нужно много, чтобы разобраться в чем-то подобном, и, возможно, ты сможешь извлечь из этого урок. Вот программа без излишеств, которая просто читает со стандартного ввода и вывода примерно в том же формате, что вы показали. Попробуйте это здесь: http://ideone.com/mt1MLS
Код
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
unsigned long address = 0;
char c;
cout << hex << setfill('0');
while( cin.good() )
{
int nread;
char buf[16];
for( nread = 0; nread < 16 && cin.get(buf[nread]); nread++ );
if( nread == 0 ) break;
// Show the address
cout << setw(8) << address;
// Show the hex codes
for( int i = 0; i < 16; i++ )
{
if( i % 8 == 0 ) cout << ' ';
if( i < nread )
cout << ' ' << setw(2) << (unsigned)buf[i];
else
cout << " ";
}
// Show printable characters
cout << " ";
for( int i = 0; i < nread; i++)
{
if( buf[i] < 32 ) cout << '.';
else cout << buf[i];
}
cout << "\n";
address += 16;
}
return 0;
}
вход
Hello there, this is a test binary file.
What do you think?
.
Выход
00000000 48 65 6c 6c 6f 20 74 68 65 72 65 2c 20 74 68 69 Hello there, thi
00000010 73 20 69 73 20 61 20 74 65 73 74 20 62 69 6e 61 s is a test bina
00000020 72 79 20 66 69 6c 65 2e 0a 57 68 61 74 20 64 6f ry file..What do
00000030 20 79 6f 75 20 74 68 69 6e 6b 3f 0a 0a 2e you think?...
template<typename byte_type = std::uint8_t>
std::string hexdump(const byte_type* buffer, std::size_t size, const std::string& title = "HEXDUMP") {
using namespace std;
ostringstream ost;
ost << title << '\n';
const auto bytes = vector<byte_type>(buffer, buffer + size);
for(auto p = cbegin(bytes) ; p < cend(bytes) ; ) {
constexpr auto ptrSize = sizeof(void*);
constexpr auto byteSize = sizeof(byte_type);
constexpr auto wordsPerRow = 4;
const auto bytesToGo = static_cast<unsigned>(std::distance(p, cend(bytes)));
const auto nBytes = std::min(ptrSize, bytesToGo);
const auto bytesPrinted = static_cast<unsigned>(std::distance(cbegin(bytes), p));
const auto isFirstRow = bytesPrinted == 0;
const auto isNewRow = (bytesPrinted % (ptrSize * wordsPerRow)) == 0;
const auto isLastRow = (p + nBytes) == cend(bytes);
if(isNewRow && !isLastRow) {
if(!isFirstRow) {
ost << '\n';
}
ost << hex << setw(ptrSize*2) << setfill('0') << bytesPrinted << " ";
}
{
for_each(p, p + nBytes, [&ost](byte_type byte) {
ost << ' ' << hex << setw(byteSize*2) << setfill('0') << static_cast<unsigned>(byte);
});
ost << " ";
}
if(isLastRow) {
ost << '\n';
}
p += nBytes;
}
return ost.str();
}