printing chars in hexadecimal manner

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
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
Thanks, that's great. But is there a way, avoiding the '0x' at begin of each number?
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
Ok thanks, sorry for my last, stupid, question ;)
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
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.
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
Thanks, but how could I get the file size?
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
Thank you so much, @JLBorges , as ever, I could learn a lot from your example :-)
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     ................
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.