Stringification макро-значения

Я столкнулся с проблемой - я должен использовать макро-значение и в качестве строки и в качестве целого числа.

 #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... */

Это перестало работать с сообщением о "случайном #", и даже если бы он работал, я предполагаю, что получил бы макро-имена stringified, не значения. Конечно, я могу подать значения к последнему методу ( "LIMIT %d ", page*RECORDS_PER_PAGE ) но это не симпатично и не эффективно. Это - времена как это, когда мне жаль, что препроцессор не рассматривал строки специальным способом и обработает их содержание точно так же, как нормальный код. На данный момент, я cludged это с #define RECORDS_PER_PAGE_TXT "10" но понятно, я не доволен этим.

Как разобраться в нем?

32
задан a3f 31 March 2015 в 01:53
поделиться

3 ответа

Макрос 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) ";"
52
ответ дан 27 November 2019 в 20:39
поделиться
#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 для оценки аргументов перед их преобразованием в строку.

3
ответ дан 27 November 2019 в 20:39
поделиться

Попробуйте двойное экранирование кавычек

#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 для цитирования.

2
ответ дан 27 November 2019 в 20:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: