宏值的字符串化
我遇到了一个问题 – 我需要使用宏值作为字符串和整数。
#define RECORDS_PER_PAGE 10 /*... */ #define REQUEST_RECORDS \ "SELECT Fields FROM Table WHERE Conditions" \ " OFFSET %d * " #RECORDS_PER_PAGE \ " LIMIT " #RECORDS_PER_PAGE ";" char result_buffer[RECORDS_PER_PAGE][MAX_RECORD_LEN]; /* ...and some more uses of RECORDS_PER_PAGE, elsewhere... */
这失败了一条关于“stray#”的消息,即使它有效,我想我会得到字符串化的宏名称,而不是值。 当然,我可以将值提供给最终方法( "LIMIT %d ", page*RECORDS_PER_PAGE
),但它既不漂亮也不高效。 当我希望预处理器不以特殊方式处理字符串并且像普通代码一样处理它们的内容时,就像这样。 现在,我用#define RECORDS_PER_PAGE_TXT "10"
表达它,但可以理解的是,我对它并不满意。
如何做到对了?
下面定义的xstr
宏将在进行宏扩展后进行字符串化。
#define xstr(a) str(a) #define str(a) #a #define RECORDS_PER_PAGE 10 #define REQUEST_RECORDS \ "SELECT Fields FROM Table WHERE Conditions" \ " OFFSET %d * " xstr(RECORDS_PER_PAGE) \ " LIMIT " xstr(RECORDS_PER_PAGE) ";"
#include #define RECORDS_PER_PAGE 10 #define TEXTIFY(A) #A #define _REQUEST_RECORDS(OFFSET, LIMIT) \ "SELECT Fields FROM Table WHERE Conditions" \ " OFFSET %d * " TEXTIFY(OFFSET) \ " LIMIT " TEXTIFY(LIMIT) ";" #define REQUEST_RECORDS _REQUEST_RECORDS(RECORDS_PER_PAGE, RECORDS_PER_PAGE) int main() { printf("%s\n", REQUEST_RECORDS); return 0; }
输出:
SELECT Fields FROM Table WHERE Conditions OFFSET %d * 10 LIMIT 10;
注意间接到_REQUEST_RECORDS以在对字符串进行字符串化之前评估参数。
尝试双重转义你的报价
#define RECORDS_PER_PAGE 10 #define MAX_RECORD_LEN 10 /*... */ #define DOUBLEESCAPE(a) #a #define ESCAPEQUOTE(a) DOUBLEESCAPE(a) #define REQUEST_RECORDS \ "SELECT Fields FROM Table WHERE Conditions" \ " OFFSET %d * " ESCAPEQUOTE(RECORDS_PER_PAGE) \ " LIMIT " ESCAPEQUOTE(RECORDS_PER_PAGE) ";" char result_buffer[RECORDS_PER_PAGE][MAX_RECORD_LEN]; int main(){ char * a = REQUEST_RECORDS; }
编译给我。 令牌RECORDS_PER_PAGE
将通过ESCAPEQUOTE
宏调用进行扩展,然后将其发送到DOUBLEESCAPE
进行引用。