C++ How-To: Print a Buffer
August 1st, 2009I was recently writing a command line application in C++ that parses raw binary. I thought it would be really nice to be able to print different parts of memory to the screen as the program runs. I’ve included well-commented code and a usage example.
1: //needed for printf()
2: #include <stdio.h>
3:
4: //needed for strlen()
5: #include <string.h>
6:
7: // prints the contents of memory in hex and ascii.
8: // starts at the location of the pointer "start"
9: // prints "length" bytes of memory.
10: void Print_Memory(const unsigned char * start, unsigned int length)
11: {
12: //create row, col, and i. Set i to 0
13: int row, col, i = 0;
14:
15: //iterate through the rows, which will be 16 bytes of memory wide
16: for(row = 0; (i + 1) < length; row++)
17: {
18: //print hex representation
19: for(col = 0; col<16; col++)
20: {
21: //calculate the current index
22: i = row*16+col;
23:
24: //divides a row of 16 into two columns of 8
25: if(col==8)
26: printf(" ");
27:
28: //print the hex value if the current index is in range.
29: if(i<length)
30: printf("%02X", start[i]);
31: //print a blank if the current index is past the end
32: else
33: printf(" ");
34:
35: //print a space to keep the values separate
36: printf(" ");
37: }
38:
39: //create a vertial seperator between hex and ascii representations
40: printf(" ");
41:
42: //print ascii representation
43: for(col = 0; col<16; col++)
44: {
45: //calculate the current index
46: i = row*16+col;
47:
48: //divides a row of 16 into two coumns of 8
49: if(col==8)
50: printf(" ");
51:
52: //print the value if it is in range
53: if(i<length)
54: {
55: //print the ascii value if applicable
56: if(start[i]>0x20 && start[i]<0x7F) //A-Z
57: printf("%c", start[i]);
58: //print a period if the value is not printable
59: else
60: printf(".");
61: }
62: //nothing else to print, so break out of this for loop
63: else
64: break;
65: }
66:
67: //create a new row
68: printf("\n");
69: }
70: }
71:
72: // Prints the contents of memory in hex and ascii.
73: // Prints the memory between and including the
74: // two "end1" and "end2" pointers.
75: void Print_Memory(const unsigned char * end1, const unsigned char * end2)
76: {
77: if(end2 >= end1)
78: Print_Memory(end1, end2 - end1 + 1);
79: else
80: Print_Memory(end2, end1 - end2 + 1);
81: }
82:
83: int main(int argc, char **args)
84: {
85: const char start [] = "hi there! You're looking at me in memory!";
86: const char * end = start + (int)strlen(start);
87:
88: Print_Memory((unsigned char *)start, (unsigned char *)end);
89:
90: return 0;
91: }
