宏值的字符串化

时间:2010-04-16 13:25:20

标签: c string concatenation c-preprocessor

我遇到了一个问题 - 我需要将宏值用作字符串和整数。

 #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"对它进行了解释,但可以理解的是,我对它并不满意。

如何做到对不对?

3 个答案:

答案 0 :(得分:47)

下面定义的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) ";"

答案 1 :(得分:3)

#include <stdio.h>

#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以在对字符串进行字符串化之前评估它们。

答案 2 :(得分:2)

尝试双重转义你的报价

#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进行引用。