9

The code I have been working on requires that I print a variable of type uint32_t in hexadecimal, with a padding of 0s and minimum length 8. The code I have been using to do this so far is:

printf("%08lx\n",read_word(address));

Where read_word returns type uint32_t. I have used jx, llx, etc. formats to no avail, is there a correct format that can be used?

EDIT:

I have found the problem lies in what I am passing. The function read_word is returns a value from a uint32_t vector. It seems that this is the problem that is causing problems with out putting hex. Is this a passing by reference/value issue and what is the fix?

read_word function:

uint32_t memory::read_word (uint32_t address) {
  if(address>(maxWord)){
        return 0;
    }

    return mem[address];

}

mem deceleration:

std::vector<uint32_t> mem=decltype(mem)(1024,0);
Dave
  • 454
  • 1
  • 7
  • 17
  • 1
    [This `` header file reference](http://en.cppreference.com/w/c/types/integer) should be helpful. Check [the format macros](http://en.cppreference.com/w/c/types/integer#Format_macro_constants) at the end. – Some programmer dude Mar 26 '17 at 12:46
  • @Someprogrammerdude Thanks, I'll look at the documentation and see If I can get it to work, not sure how to get PRIx32 working with padding – Dave Mar 26 '17 at 12:58
  • It just specifices the type. No difference. – Karoly Horvath Mar 26 '17 at 12:59
  • @KarolyHorvath I'm using `printf("%08PRIx32\n",read_word(address));` and receiving `%08PRIx32` as output. – Dave Mar 26 '17 at 13:06
  • The macros that start with `PRI` cannot be inside the format string. Look at WhozCraig's answer closely. – Adrian McCarthy Mar 26 '17 at 16:22
  • @AdrianMcCarthy Thanks, didn't realise that before. After trying that I have found that it lies in the fact I am trying to use a value returned from a vector, and when I return a normal constant from word address It all works. Do you have any idea what this could be attributed to? – Dave Mar 26 '17 at 16:33
  • @Dave: Show the prototype/function signature for read_word. – Adrian McCarthy Mar 26 '17 at 16:38
  • @AdrianMcCarthy `uint32_t read_word (uint32_t address);` – Dave Mar 26 '17 at 16:39
  • @Dave: It makes no difference where read_word gets the value. It's returning a `uint32_t`, so it should work just as if you had a variable there. WhozCraig's answer should work for you. – Adrian McCarthy Mar 26 '17 at 17:01
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139086/discussion-between-dave-and-adrian-mccarthy). – Dave Mar 26 '17 at 17:06

2 Answers2

11

To do this in C++ you need to abuse both the fill and the width manipulators:

#include <iostream>
#include <iomanip>
#include <cstdint>

int main()
{
    uint32_t myInt = 123456;
    std::cout << std::setfill('0') << std::setw(8) << std::hex << myInt << '\n';
}

Output

0001e240

For C it gets a little more obtuse. You use inttypes.h

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>


int main()
{
    uint32_t myInt = 123456;
    printf("%08" PRIx32 "\n", myInt);
    return 0;
}

Output

0001e240

Note that in C, the constants from inttypes.h are used with the language string-concatenation feature to form the required format specifier. You only provide the zero-fill and minimum length as a preamble.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • 1
    For me `printf("%08x\n", value);` works fine where `uint32_t value = 0xabcd;`, `stdio.h` and `stdint.h` included only. – Bence Kaulics Mar 26 '17 at 13:16
  • We seem to be onto something with the formatting from the C++ version, however the output is still coming out in decimal. E.g. when read_word returns a value of 10 (type uint32_t) and is used in the C++ method it will print `00000010`; unfortunately not `0000000a`. If I set a constant in the cout in place of `myInt` it works, so perhaps it is a problem with the return? – Dave Mar 26 '17 at 13:21
  • 1
    A much less ugly solution that works for arbitrary types you don't have macros for is `printf("%08jx", (uintmax_t)value);` – R.. GitHub STOP HELPING ICE Mar 26 '17 at 15:39
  • @R Seems like a good solution, as per my edit in the OP there seems to be another underlying error, would you happen to know why this is caused? – Dave Mar 26 '17 at 15:54
  • Is the order of flags mandatory in std::setfill('0') << std::setw(8) << std::hex ?? Is it the same as std::hex << std::setfill('0') << std::setw(8) ? – kingsjester Nov 22 '22 at 12:25
2

%jx + typecast

I think this is correct:

#include <stdio.h>
#include <stdint.h>

int main(void) {
    uint32_t i = 0x123456;
    printf("%08jx\n", (uintmax_t)i);
    return 0;
}

compile and run:

gcc -Wall -Wextra -pedantic -std=c99 main.c
./a.out

Output:

00123456

Let me know if you can produce a failing test case.

Tested in Ubuntu 16.04, GCC 6.4.0.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • Hey there, would you mind drop a link. I really cannot found the %j% specifier. I search https://en.cppreference.com/w/c/types/integer and also googled. Thank you. – jian Jul 20 '22 at 06:47
  • @Mark see the table at: https://en.cppreference.com/w/cpp/io/c/fprintf . `j` + `x` should be `uintmax_t`. – Ciro Santilli OurBigBook.com Jul 20 '22 at 08:19