0
printf("%s", 0x216f6c6c6548); // "Hello!" reversed

It should print "Hello!" but it doesn't. I expected the same result of:

long long ll = 0x216f6c6c6548;
printf("%s", &ll);

or

printf("%s", "Hello!");

Is it possible to print a number as a string?

UPDATE

Is it possible to print directly a number as a string?

untitled
  • 389
  • 4
  • 13

2 Answers2

6

You have to extract the characters from the number:

print_ull_as_str (unsigned long long ll)
{
    while (ll != 0) { printf("%c", (char )(ll & 0xffu)); ll >>= 8; }
}
Doug Currie
  • 40,708
  • 1
  • 95
  • 119
2

After accept answer

Easy to print directly. Use a compound literal to form the string.

#include <stdio.h>
#define SBprint(x) ((char [8+1]){ \
    1ULL*x>>0 , 1ULL*x>> 8, 1ULL*x>>16, 1ULL*x>>24, \
    1ULL*x>>32, 1ULL*x>>40, 1ULL*x>>48, 1ULL*x>>56, 0})


int main(void) {
  printf("%s", SBprint(0x216f6c6c6548));
  printf("%s", SBprint(0x65726120776F480A));
  printf("%s", SBprint(0x0A3F756F7920));
}

Output

Hello!
How are you?

If your compiler use little endian, even simpler.

#define SBprint(x) ((union {long long ll[2]; char s[sizeof(long long)+1]; }){ {x, 0} }).s
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Relative to first code (very illuminating), I think it isn't the true output, beacuse of carriage return (and there isn't newline). Correct? – untitled Jan 29 '16 at 20:52
  • Relative to the second one, after the cast to union, what does `{ {x, 0} }` mean? – untitled Jan 29 '16 at 20:58
  • @Simone Bonato Incorrect - it is the true output. `stdout` is typically in "text mode". That will translate the `'\n'`or `0D` that was sent by `printf()` to do whatever is appropriate for the console end-of-line. In this case the output screen experienced a cursor re-positioning to the beginning of the next line (carriage Return / Line Feed). – chux - Reinstate Monica Jan 29 '16 at 20:58
  • @Simone Bonato There is no "cast to union". Think of `printf("Hello");` `"Hello"` is a string literal. This code creates a _compound literal_ of type `union {long long ll[2]; char s[sizeof(long long)+1]; }`. The `{x, 0}` populates that literal with `x` and `0`. Then when that literal's field `.s` is passed to `printf()`, it is converted to the address of first element of the array `.s[0]`, which happens to contain the least significant byte of `x` stored in it. – chux - Reinstate Monica Jan 29 '16 at 21:04
  • So `printf()` receives the address to the first byte of an array. The array contains `'H'`,`'e'`,`l'`, .... In case the most-significant-byte of `x` was non-zero, the `0` of `{x, 0}` insures a whole lot of null characters follow and so the array of characters contain a null character, thus making the array a _string_. – chux - Reinstate Monica Jan 29 '16 at 21:10
  • IMO, code _can_ "print the number without using a variable". This code just uses literals. – chux - Reinstate Monica Jan 29 '16 at 21:12
  • But can 0 be omitted? If I have `typedef union{ int i; char ch; }U;` and `printf("%c",(U){0x41, 0}.i);` is it considered cast or compound literal? (I'm a bit off topic, sorry) – untitled Jan 29 '16 at 21:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/102036/discussion-between-chux-and-simone-bonato). – chux - Reinstate Monica Jan 29 '16 at 21:13
  • Aren't there any overflows? – untitled Jan 31 '16 at 08:38
  • @Simone Bonato Use `unsigned char [9]` instead of `char [8+1]` to quell overflow concerns. – chux - Reinstate Monica Jan 31 '16 at 21:42