Я столкнулся с проблемой - я должен использовать макро-значение и в качестве строки и в качестве целого числа.
#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"
но понятно, я не доволен этим.
Как разобраться в нем?
Макрос 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_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
для цитирования.