提问者:小点点

宏值的字符串化


我遇到了一个问题--我需要同时使用一个string和Integer的宏值。

 #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”来处理它,但可以理解,我对此并不满意。

怎么把它弄对?


共2个答案

匿名用户

下面定义的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 <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_RECORDESS来计算参数,然后再对它们进行字符串化。