printing chars in hexadecimal manner

Mar 9, 2019 at 1:33pm
I want to print plain chars as hex numbers, is there a smooth way doing such?

That's how I tackled it, but it would great if I could avoid the converting function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>

std::string charToHex( char ch)
{
     char first, second;
     
     first = ch / 0x10;
     second = ch % 0x10;
     
     if (first < 10) { first += '0'; }
     else {
         first -= 10;
         first += 'A';
     }
     if (second < 10)  { second += '0'; }
     else {
         second -= 10;
         second += 'A';
     }
     return std::string() + first + second;
}

int main()
{   
    for( char c : "hello") std::cout << charToHex(c);
}

Is it able printing a char in hexadecimal manner without needing a converting function?
Last edited on Mar 9, 2019 at 1:43pm
Mar 9, 2019 at 1:39pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
#include <iomanip>

int main()
{
    const std::string str = "hello" ;

    // print characters
    for( char c : str ) std::cout << c << ' ' ;
    std::cout << '\n' ;

    // print hex values of characters
    std::cout << std::hex << std::showbase ;
    for( int c : str ) std::cout << c << ' ' ;
    std::cout << '\n' ;
}

http://coliru.stacked-crooked.com/a/d6e0c03989d2831d
Mar 9, 2019 at 1:46pm
Thanks, that's great. But is there a way, avoiding the '0x' at begin of each number?
Mar 9, 2019 at 1:48pm
std::cout << std::hex << std::noshowbase << n << '\n';

I think this is actually the default and the above is turing the 0x ON for you.
Last edited on Mar 9, 2019 at 1:49pm
Mar 9, 2019 at 1:51pm
Ok thanks, sorry for my last, stupid, question ;)
Mar 9, 2019 at 2:06pm
Heh, it is easy to overlook unfamiliar tags in cout statements. Without the std:: on them, its very frustrating to tell variables and formatting apart for the less commonly used formatting keywords. The std:: contributes a lot here where most of the time it is visual clutter.
Last edited on Mar 9, 2019 at 2:07pm
Mar 9, 2019 at 2:21pm
I tried to apply this stuff at writing a hex-printing program, but only spits garbage if I try it on binary files.
I guess, that's because I set the wrong properties to the ostream. But I'm a relative rookie dealing with the settings of streams, so I don't know what to do.

Here the code of my hex-printer:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cctype>

// How much chars get printed at a line.
const int MAX_ITEMS_PER_LINE = 16;

void printHelp();
std::string charToHex( char);  // Help me avoid this function



int main( int argc, char **argv)
{
    if (argc < 2) { printHelp(); return 1; }  
    std::ifstream is(argv[1]);
    if (!is) { printHelp(); return 2; }    
    std::ostream &os = std::cout;
    if (!os) return 3;

    long int lineNo = 0;    
    int column = 0;
    char data;
    while( is.get(data) )
    {
        if (column == 0)
        {
            os << std::setw(6) << std::hex
               << lineNo * MAX_ITEMS_PER_LINE << ": ";
        }
        if (isgraph(data) )
        {
             os << " " << data << " ";
        }
        else if (data == 32) os << "   ";   // space
        else if (data == 10) os << "\\n ";  // new line
        else if (data == 7)  os << "\\a ";  // bell
        else if (data == 8)  os << "\\b ";  // backspace
        else if (data == 9)  os << "\\t ";  // horizontal tabtab
        else if (data == 11) os << "\\v ";  // vertical tab
        else if (data == 12) os << "\\f ";  // form feed
        else if (data == 13) os << "\\r ";  // carriage return
        else { 
            os << charToHex(data);
 //           os << std::hex << data << ' '; // this dosen't work
        }
        ++column;
           
        if (column >= MAX_ITEMS_PER_LINE)
        {
            os.put('\n');
            column = 0;
            ++lineNo;
        }
    }
    os << '\n';
    return 0;
}

void printHelp()
{
     std::cout << "Usage: <prog_name> <input_file>\n"
          << "Prints a pseudo-hex to standard output (std::cout)\n";
}

// Using this function I try to avoid
//
std::string charToHex( char ch)
{
     char first, second;
     
     first = ch / 0x10;
     second = ch % 0x10;
     
     if (first < 10) { first += '0'; }
     else {
         first -= 10;
         first += 'A';
     }
     if (second < 10)  { second += '0'; }
     else {
         second -= 10;
         second += 'A';
     }
     return std::string() + first + second;
}


I would be glad if someone could help me avoid the use of the charTohex() function.
Mar 9, 2019 at 2:29pm
this approach?
ifstream inf;
inf.open(name, ios::binary);
..
inf.read(buffer, filesizeinbytes);
..
for(.. filesizeinbytes)
cout << hex << buffer[index];

keep in mind that text files ARE 'binary' files. The language makes a distinction so you can use tools that do specific things because its 'text' that are mighty handy, but the above will work on text files too (its going to print hex for the end of lines and other whitespace, but it works, and remember that eol may be 2 chars long, 10/13 byte values usually).
Last edited on Mar 9, 2019 at 2:33pm
Mar 9, 2019 at 2:55pm
Thanks, but how could I get the file size?
Mar 9, 2019 at 3:36pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cctype>

void dump_char( char c )
{
    if( std::isprint(c) ) std::cout << c ;
    else switch(c)
    {
        case 7 : std::cout << "\\a" ; break ;  // bell
        case 8 : std::cout << "\\b" ; break ;  // backspace
        case 10 : std::cout << "\\n" ; break ;  // line feed
        case 11 : std::cout << "\\v" ; break ;  // vertical tab
        case 12 : std::cout << "\\f" ; break ;  // form feed
        case 13 : std::cout << "\\r" ; break ;  // carriage return
        default: std::cout << '.'  ; // unprintable character
    }
}

constexpr int N = 16 ;

void dump( int line_cnt, const std::string& buf )
{
    std::cout << std::hex << std::setw(4) << std::setfill('0') << line_cnt*N
              << " - " << std::setw(4) << line_cnt*N + N-1 << "    " ;

    for( int c : buf )
        std::cout << std::hex << std::setw(2) << std::setfill('0') << c << ' ' ;
    std::cout << "    " ;
    for( auto i = buf.size() ; i < N ; ++i ) std::cout << "   " ;

    for( char c : buf ) dump_char(c);
    std::cout << '\n' ;
}

void hex_dump( const std::string& path_to_file )
{
    if( std::ifstream file{ path_to_file, std::ios::binary } )
    {
        int line_cnt = 0 ;

        std::string buf ;
        char c ;
        while( file.get(c) )
        {
            buf += c ;
            if( buf.size()%N == 0 )
            {
                dump( ++line_cnt, buf ) ;
                buf.clear() ;
            }
        }

        if( !buf.empty() ) dump( ++line_cnt, buf ) ;
    }
}

int main()
{
    hex_dump( __FILE__ ) ;
}

http://coliru.stacked-crooked.com/a/a4cfba8a449669d5
Mar 9, 2019 at 4:12pm
Thank you so much, @JLBorges , as ever, I could learn a lot from your example :-)
Mar 9, 2019 at 6:01pm
The program of JLBorges works good, but the output is somewhat erroneous, At the time I'm trying to find the error, but I have no clue where I need to search.

Here some output:
1
2
3
4
5
6
7
000000 - 00000f    7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00     .ELF............
000010 - 00001f    03 00 3e 00 01 00 00 00 fffffff0 04 00 00 00 00 00 00     ..>.............
000020 - 00002f    40 00 00 00 00 00 00 00 ffffffe8 18 00 00 00 00 00 00     @...............
000030 - 00003f    00 00 00 00 40 00 38 00 09 00 40 00 1c 00 1b 00     ....@.8...@.....
000040 - 00004f    06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00     ........@.......
000050 - 00005f    40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00     @.......@.......
000060 - 00006f    fffffff8 01 00 00 00 00 00 00 fffffff8 01 00 00 00 00 00 00     ................
Mar 9, 2019 at 11:28pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cctype>

void dump_char( char c )
{
    if( std::isprint( static_cast<unsigned char>(c) ) ) std::cout << c ; // ****
    else switch(c)
    {
        case 7 : std::cout << "\\a" ; break ;  // bell
        case 8 : std::cout << "\\b" ; break ;  // backspace
        case 10 : std::cout << "\\n" ; break ;  // line feed
        case 11 : std::cout << "\\v" ; break ;  // vertical tab
        case 12 : std::cout << "\\f" ; break ;  // form feed
        case 13 : std::cout << "\\r" ; break ;  // carriage return
        default: std::cout << '.'  ; // unprintable character
    }
}

constexpr int N = 16 ;

void dump( int line_cnt, const std::string& buf )
{
    std::cout << std::hex << std::setw(4) << std::setfill('0') << line_cnt*N
              << " - " << std::setw(4) << line_cnt*N + N-1 << "    " ;

    for( unsigned char c : buf ) // ****
        std::cout << std::hex << std::setw(2) << std::setfill('0') << int(c) << ' ' ; // ****
    std::cout << "    " ;
    for( auto i = buf.size() ; i < N ; ++i ) std::cout << "   " ;

    for( char c : buf ) dump_char(c);
    std::cout << '\n' ;
}

void hex_dump( const std::string& path_to_file, int max_lines = 9999 )
{
    if( std::ifstream file{ path_to_file, std::ios::binary } )
    {
        int line_cnt = 0 ;

        std::string buf ;
        char c ;
        while( file.get(c) && line_cnt < max_lines )
        {
            buf += c ;
            if( buf.size()%N == 0 )
            {
                dump( ++line_cnt, buf ) ;
                buf.clear() ;
            }
        }

        if( !buf.empty() ) dump( ++line_cnt, buf ) ;
    }
}

int main()
{
    hex_dump( "a.out", 100 ) ; // print first 100 lines (1600 bytes)
}

http://coliru.stacked-crooked.com/a/95a9744d78793afb
Topic archived. No new replies allowed.