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

使用C宏构造字符串/字符转义序列,c,macros,C,Macros,我想寻找C宏,比如:CHR(0x20),它将生成字符串“\x20” 我相信那是不可能的。想证明我错了吗?;-) 您可以通过生成一个大的头文件来实现这一点,例如使用一点Python: 范围(0256)内x的: 打印“#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(

我想寻找C宏,比如:CHR(0x20),它将生成字符串“\x20”


我相信那是不可能的。想证明我错了吗?;-)

您可以通过生成一个大的头文件来实现这一点,例如使用一点Python:

范围(0256)内x的
:
打印“#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));
}

如果您接受调用
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));
}
这就是我们希望在宏运行时看到的


你也可以这样做:

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

达到预期效果。

您想达到什么目的?那个宏比普通的形式更容易打字…我认为它不能,它是通过宏删除字符的一部分。当然,说了这么多,看起来你试图以错误的方式解决错误的问题。无论你真正的问题是什么,都必须有一个更整洁的解决方案。天才!明白了,C预处理器!;-)我曾考虑过(ab)使用C99复合文本,但那肯定不起作用,因为我实际上需要做的是:“#定义LSTR(s)CHR(sizeof(s)-1)s | | intern|u str(LSTR(“foo”);”,也就是说,最后需要定义字符串和静态字符串。是的,更简单的解决方案是使用C++11的constexpr(特别是因为我还需要在其中放入哈希),但人们不想使用C++11,坚持使用古老的C,请想想……但是的,C预处理器不执行sizeof(),所以前面评论中的LSTR()宏无法工作。不管怎样,原来的问题回答得很好。必须为实际情况编写自定义预处理器。。。
return printf("%s", ("\x20"));
#define CHR(x) ((char[2]){(x), 0x0})