简体   繁体   中英

Construct string/char escape sequence using C macro

I'd be looking for C macro like: CHR(0x20) which would produce string "\\x20".

I'm sure that's not possible. Care to prove me wrong? ;-)

You can do this by generating a large header file, eg using a little bit of Python:

for x in range(0,256):
  print '#define BODGE_0x%x \\x%x' % (x,x)

And then use the output of that in C:

#include <stdio.h>

#include "bodge.h"

#define xstr(s) str(s)
#define str(s) #s
#define XCHR(x,y) (xstr(x##y))
#define CHR(x) xstr(BODGE_##x)

int main() {
  return printf("%s\n", CHR(0x20));
}

Which does exactly what you asked for, gcc -E shows:

return printf("%s\n", "\x20");

It's possible (but fiddly) to do something less crude if you accept calling CHR(20) to imply hex without the 0x prefix.

The obvious solution would be to build a macro that expands to:

printf("%s", "\x" "20");

which is fairly easy to do with one level of indirection, and the obvious assumption would be that the compile time concatenation of strings would handle this. Unfortunately that solution isn't viable because of the point in translation when the escape sequence gets handle. GCC therefore gives the error:

error: \x used with no following hex digits

We can however work around that and cause the string "\\x20" to be generated by using a pre-processor concatenation ( ## ) in conjunction with the "usual" preprocessor stringification indirection:

#include <stdio.h>

#define xstr(s) str(s)
#define str(s) #s
#define XCHR(x,y) (xstr(x##y))
#define CHR(y) XCHR(\x,y)

int main() {
  return printf("%s", CHR(20));
}

This does work and, gcc -E shows:

return printf("%s", ("\x20"));

which is what we'd hope to see when the macro works.


You could also do:

#define CHR(x) ((char[2]){(x), 0x0})

which has the desired effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM