宏:从字符字面量转换为字符串字面量

10

在C语言中,是否有一种方法可以使用宏从字符字面量创建字符串字面量?

例如,我有以下内容:

'a'

我想创建一个字符串字面量。
"a"

为了澄清问题:

#define A 'a'

write(fd, "x=" CHAR2STRING(A) "\n", 4);

我的问题是如何定义宏CHAR2STRING。

1
@WhozCraig - 它应该在编译时进行评估。我希望它以与我直接在代码中使用“a”相同的方式存储(而不是指示编译器生成它)。 - martinkunev
那么我认为这不可能发生,但如果有人想出了一种方法,我会真的很好奇。 (现在对我来说太晚了,而且缺乏咖啡因)。 - WhozCraig
1
“A”宏必须是一个字符字面量,不能是其他东西,比如97或0x61?难道你不能通过将“A”变成字符串字面量,并为其他使用“A”的情况编写“STRING2CHAR(A)”宏来反其道而行之吗? - M Oehm
3
我认为这是不可能的。但是你可以定义 a,然后从中生成 'a'"a" 两个字符串。 - M.M
2
@mafso 使用 *"a" 代替 'a' - BLUEPIXY
显示剩余6条评论
4个回答

2
-问题评论摘要-
这似乎是不可能实现的。作为替代方案,可以定义字符串字面量并编写STRING2CHAR宏:
#define A "a"
#define STRING2CHAR(s) (*(s))
write(fd, "x=" A "\n", 4);
putchar(STRING2CHAR(A));

或者

#define A a
#define XSTR(s) #s
#define SYM2CHAR(sym) (*XSTR(sym))
#define SYM2STRING(sym) XSTR(sym)

表达式*“a”不是编译时常量(因此不能用作具有非自动存储期限的对象的初始化程序,非VLA数组长度,case标签或位域宽度),尽管编译器应该能够在编译时计算它(已使用Gcc和Clang进行测试)。
建议由 M Oehm Matt McNabb提供。

1
尽管我有点晚了,但我为 ASCII(7 位)字符想出了一个解决方案:
#define CHAR2STR(c) ((char*[]){ \
    "\0", "\1", "\2", "\3", "\4", "\5", "\6", "\a", \
    "\b", "\t", "\n", "\v", "\f", "\r", "\16", "\17", \
    "\20", "\21", "\22", "\23", "\24", "\25", "\26", "\27", \
    "\30", "\31", "\32", "\33", "\34", "\35", "\36", "\37", \
    " ", "!", "\"", "#", "$", "%", "&", "'", \
    "(", ")", "*", "+", ",", "-", ".", "/", \
    "0", "1", "2", "3", "4", "5", "6", "7", \
    "8", "9", ":", ";", "<", "=", ">", "?", \
    "@", "A", "B", "C", "D", "E", "F", "G", \
    "H", "I", "J", "K", "L", "M", "N", "O", \
    "P", "Q", "R", "S", "T", "U", "V", "W", \
    "X", "Y", "Z", "[", "\\", "]", "^", "_", \
    "`", "a", "b", "c", "d", "e", "f", "g", \
    "h", "i", "j", "k", "l", "m", "n", "o", \
    "p", "q", "r", "s", "t", "u", "v", "w", \
    "x", "y", "z", "{", "|", "}", "~", "\177", \
})[c]

这可以扩展到完整的ASCII表格,使用"\180","\181" ...(所有数字均为八进制,因此没有\178!),但我认为这并不是很有用,因为它是一个宏。 这个技巧之所以有效,是因为利用了匿名字符串数组(“table”)的初始化位置,如果字符已知,编译器应该会自动进行优化。

gcc错误:test.c:3:21:错误:被调用的对象不是函数或函数指针 3 |#define CHAR2STR(c)((char * []){ \ - Mah35h

1
你可以这样做。
#define A 'a'
#define X(macro) #macro
#define CHAR2STRING(macro) X(macro)

printf("%s\n", CHAR2STRING(A));

你将会得到 'a' 而不是 a,但也许对您来说这没关系。


0

不是很优雅,但它可以工作:

#define STRING_ME(tgt, ch) tgt[0]=ch;tgt[1]='\0'

假设tgt有2个字符的空间。或许你能举个例子说明你想要它看起来是什么样子?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接