web-dev-qa-db-ja.com

マクロ値の文字列化

問題が発生しました-文字列と整数の両方としてマクロ値を使用する必要があります。

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

これは、「迷子#」に関するメッセージで失敗し、それが機能したとしても、値ではなく、マクロ名を文字列化したものになると思います。もちろん、最終的なメソッド("LIMIT %d ", page*RECORDS_PER_PAGE)しかし、それはかなりも効率的でもありません。プリプロセッサが文字列を特別な方法で処理せずに、通常のコードと同じようにコンテンツを処理するようにしたいときは、このようなときです。とりあえず、#define RECORDS_PER_PAGE_TXT "10"しかし当然のことながら、私はそれについて満足していません。

それを正しくする方法は?

33
SF.

以下で定義されている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
#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
Mike Weller

二重引用符をエスケープしてみてください

#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_PAGEESCAPEQUOTEマクロ呼び出しによって展開され、DOUBLEESCAPEに送信されて引用されます。

2
Scott Wales