-1
TLDR;

Default output of pointers with c++ iostream is of the form 0xdeadbeef. What I want is pointers to be output in the form #xdeadbeef.

Problem

For testing purposes I output internal data of some c++ program in form of s-expressions, so I can have in the future the option to use Common Lisp to reason about the output. Now, hex numbers are written in the form #xdeadbeef and iostream default is using the C/C++ typical 0x... syntax.

So, after a bit of reading, I think I am close to finding a solution... only, at least on cppreference.com, there is not enough (demo code or explanations) to allow me to understand, how I am exactly supposed to solve this.

#include <iostream>
#include <locale>
#include <sstream>
#include <string>

struct lispy_num_put : std::num_put<char> {
  iter_type do_put(iter_type s, std::ios_base& f,
           char_type fill, const void* p) {
    std::ostringstream oss;
    oss << p;
    std::string zwoggle{oss.str()};
    if (zwoggle.length() > 2 && zwoggle.starts_with("0x")) {
      zwoggle[0] = '#';
    }
    // ... NOW WHAT TO DO??? I.e how to send the string along?
  }
};
// ...

As you can see, I now have the string representation of how I want to see the pointer in the output. Only it is unclear to me, how to send that string now into the output stream.

Later, I will have to use some imbue() thingy to make this struct used by my output stream. I think, that part I can figure out myself.

BitTickler
  • 10,905
  • 5
  • 32
  • 53
  • A simple workaround would be to define a function/struct wrapper to do the output instead of modifying the default behavior. – user202729 Nov 08 '21 at 09:25
  • Looks like like you can use the default `do_put` -- see [C++ custom stream manipulator that changes next item on stream - Stack Overflow](https://stackoverflow.com/questions/799599/c-custom-stream-manipulator-that-changes-next-item-on-stream). – user202729 Nov 08 '21 at 09:25
  • @user202729 I assumed this is the idiomatic way of this use case, supported by STL... – BitTickler Nov 08 '21 at 09:26
  • I think changing the behavior of printing pointer globally would be quite unexpected by the programmer however. Wrapping in struct would make it explicit (like `std::cout<< PrintPointerAsLisp{my_pointer};`) – user202729 Nov 08 '21 at 09:27
  • This is an example for a whole class of use cases, which are not really explained (at least I did not find stuff while googling...). The same solution could also apply for a reincarnated roman emperor who wants to see their numbers as roman literals ;) The problem is, how to use `std::num_put` for alternate formatting... – BitTickler Nov 08 '21 at 09:31
  • Maybe make the question ask for specific clarification regarding that answer instead. Somehow I find it okay to understand (it gets the user's input in the parameter, then print the modified output) – user202729 Nov 08 '21 at 09:33

1 Answers1

1

Use your iter_type s parameter to output characters.

*s++ = '#'; // outputs a hash 
while (...) *s++ = ...; // outputs digits
return s;
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243