#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
using namespace std;
namespace fs = filesystem;
void printhex(char *path) {
// ios::binary 플래그를 사용해 이진모드로 파일 열기
ifstream file(path, ios::binary);
if (!file) {
cerr << "failed to open file: " << path << endl;
return;
}
cout << endl << endl;
cout << "file: " << path << endl;
cout << endl;
cout << "offset(h) ";
for (int i = 0; i < 16; i++)
{
cout << setw(2) << setfill('0') << hex << uppercase << i << " ";
}
cout << " ascii" << endl;
cout << "--------- ";
for (int i = 0; i < 16; ++i) {
cout << "-- ";
}
cout << " ----------------" << endl;
// 한줄에 16 Byte 출력. offset은 uint32_t
unsigned int offset = 0;
// 헥사값을 담을 버퍼는 uint8_t, 배열로 해도 된다.
// 벡터는 동적으로 메모리를 할당하지만 생성시 아래처럼 요소 개수를 지정하면 연속된 메모리에 배치된다.
vector<unsigned char> buffer(16);
// null 포함 아스키값 담을 버퍼
char ascii[17] = {0, };
while (true)
{
// vector.data()는 벡터의 시작 주소를 반환한다
// read() 읽어온 데이터를 저장할 문자열 버퍼의 포인터인 char* s 와 읽어올 문자 수인 streamsize n 을 인자로 받는다.
file.read(reinterpret_cast<char*>(buffer.data()), buffer.size());
// file.gcount()는 최근 read() 호출로 읽은 바이트 수를 반환한다.
int bytesread = file.gcount();
if (bytesread == 0) break;
// 16진수 대문자 출력, 출력 폭은 8, 나머지는 '0'으로 채운다.
cout << setw(8) << setfill('0') << hex << uppercase << offset << " ";
for (int i = 0; i < bytesread; i++)
{
// char를 int로 캐스팅. 아직 버퍼 비우기 전이라 출력형식은 그대로 내려온다.
cout << setw(2) << static_cast<int>(buffer[i]) << " ";
// 32(공백 문자)부터 126('~' 문자)까지는 출력 가능한 문자(isprint())로 그대로 출력하고 아닌경우 '.' 출력
ascii[offset % 16] = (buffer[i] >= 32 && buffer[i] <= 126) ? buffer[i] : '.';
offset++;
}
if (offset % 16 == 0)
{
ascii[16] = '\0';
}
else
{
ascii[offset % 16] = '\0';
for(int i = 0; i < 16 - (offset % 16) ; i++) cout << " ";
}
cout << ascii << endl;
}
file.close();
cout << endl << endl;
}
int main(int argc, char* argv[]) {
// 인자 개수 확인
if (argc < 2) {
cout << "usage: " << argv[0] << " <filename>" << endl;
return 1;
}
printhex(argv[1]);
return 0;
}
'프로그래밍 > C++' 카테고리의 다른 글
char, wchar_t, TCHAR (0) | 2023.09.15 |
---|---|
C++ ] 시스템 명령어 실행 (0) | 2023.07.11 |
C++ ] Manipulator와 iomanip 헤더 (0) | 2023.05.28 |
C++ ] static_cast와 reinterpret_cast. 그 외 const_cast, dynamic_cast (0) | 2023.05.28 |
C++ ] 예외처리 try-catch (0) | 2023.05.28 |