如何在连接预处理器宏中添加空格?

3
给定以下内容,我该如何得到一个输出为ONE TWO THREE的结果?我似乎无法想出在??中应该填什么才能得到预期的连接行为。你不能使用#define来定义单个空格。
#include <iostream>
#define STRINGIFY(x) #x
#define STRINGIFYMACRO(y) STRINGIFY(y)

#define CONCAT2(X,Y) X ##  Y
#define CONCAT(X,Y) CONCAT2(X,Y)

#define CAT \
ONE     \
TWO


#define DOG \
THREE

#define BAT CONCAT(CONCAT(CAT,?? ),DOG)

int main()
{
    std::cout << STRINGIFYMACRO(BAT) << std::endl;
    return 0;
}

7
首先将字符串转化为字符串形式,然后再将它们连接起来。不能反过来做。一个标记中不能有空格,但是一个字符串可以包含空格。 - Eugene Sh.
#ifdef __cplusplus / #error wrong compiler / #endif - pmg
提示:char *str = "one" " " "two" " " "three";char *str = "one two three"; 是相同的。 - user3386109
#define BAT CAT DOG? - melpomene
1个回答

3
##运算符用于组合两个连续的记号。它不能用于组合不是记号的内容(例如空格),如果结果不是有效的(预处理)记号,则也不能使用它。
换句话说,不要使用##来组合字符串。这不是它的用途,也行不通。
请记住,在C++中,连续的字符串将被编译器连接起来。因此,通常不需要连接字符串的内容。即使必须连接内容,也可以在不使用记号连接的情况下完成,因为字符串的内容不是一个标记。(仅在尝试从多个组件创建计算的#include文件名时才需要这样做。)
还有一件有用的事情需要知道,即宏替换中的空格(不在任何一端)会缩减为单个空格字符,并由字符串化运算符保留。
因此,如果您对单个空格字符没有意见,只需执行以下操作:
#include <iostream.h>
#define STRINGIFY(x) #x
#define STRINGIFY_EXPANDED(x) STRINGIFY(x)

#define CAT ONE TWO
#define DOG THREE
#define BAT CAT DOG

int main() {
  std::cout << STRINGIFY_EXPANDED(BAT) << '\n';
  return 0;
}

在线试用!

否则,您可以将字符串化为多个部分,并按需连接这些部分:

#define DOG STRINGIFY(ONE) "   " STRINGIFY(TWO)
#define CAT STRINGIFY(THREE)
#define BAT DOG "\t" CAT

在此在线尝试!


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