使用C宏构造字符串/ char转义序列

时间:2013-12-29 22:13:56

标签: c macros

我一直在寻找C macro,如:CHR(0x20)会产生字符串“\ x20”。

我确信这是不可能的。小心证明我错了? ; - )

1 个答案:

答案 0 :(得分:1)

您可以通过生成一个大的头文件来完成此操作,例如:使用一点Python:

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

然后在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));
}

您提出的确切要求,gcc -E显示:

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

如果您接受调用CHR(20)暗示没有0x前缀的十六进制,那么可以(但很繁琐)做一些不那么粗糙的事情。

显而易见的解决方案是构建一个扩展为:

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

这对于一个间接级别来说相当容易,显而易见的假设是字符串的编译时间连接会处理这个问题。不幸的是,这个解决方案是不可行的,因为当转义序列被处理时,转换点。 GCC因此给出错误:

error: \x used with no following hex digits

然而,我们可以解决这个问题,并通过使用预处理器连接(##)和“通常”预处理器字符串化间接来生成字符串“\ x20”:

#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));
}

这确实有效,gcc -E显示:

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

这是我们希望在宏工作时看到的内容。


你也可以这样做:

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

具有预期的效果。