重複の可能性:
プリプロセッサ トークンを文字列に変換する
#define num 1234
num に基づいて「const char*」を定義したいのですが、サンプルでは次のようになります。
#define num_str "1234"
これを実現するマクロ ステートメントを記述できますか? 注意: 1234 は変更されます。
ありがとう。
重複の可能性:
プリプロセッサ トークンを文字列に変換する
#define num 1234
num に基づいて「const char*」を定義したいのですが、サンプルでは次のようになります。
#define num_str "1234"
これを実現するマクロ ステートメントを記述できますか? 注意: 1234 は変更されます。
ありがとう。
はい、できますが、マクロ置換は少し奇妙に見える場合があります。ダブル マクロ置換には理由があります。しばらく考えてみると、なぜそれが必要なのかが明らかになります。
#define STRINGIZER_(exp) #exp
#define STRINGIZER(exp) STRINGIZER_(exp)
#define NUM 1234
int main(int argc, char *argv[])
{
const char *p = STRINGIZER(NUM);
printf("%s\n",p);
return EXIT_SUCCESS;
}
これを実行する:
1234
二重置換の理由: 一見すると、これで問題が解決すると思うかもしれません。
#define STRINGIZER(exp) #exp
#define NUM 1234
int main(int argc, char *argv[])
{
const char *p = STRINGIZER(NUM);
printf("%s\n",p);
return EXIT_SUCCESS;
}
しかし、これは以下を生成します:
NUM
これは私たちがやろうとしていることではありません。最初に NUM マクロを実際に展開したい場合は、それがあなたがしなければならないことです: 展開を強制します。プリプロセッサが最初に中間展開を介して置換することを強制することにより(この回答の上部に示すように)、渡されたマクロが最初に展開され、次に文字列化されます。
補足:この手法は、通常の文字列を保持する定義済みプリプロセッサ マクロのワイド文字バージョンを生成する場合に特に役立ちます。たとえば、__FILE__
マクロ。これのワイド文字バージョン (先頭に 'L' を付けた文字列) が必要だとすると、最初はこれでうまくいくと思うかもしれません:
#define WIDESTR(str) L##str
__FILE__
しかし、これを次のように拡張します。
const wchar *p = WIDESTR(__FILE__);
コンパイラ エラーが発生します。"Undefined identifier: L__FILE__"
では、どうすればこれに対処できるでしょうか。上記と同じ方法です。
#define WIDESTR_(str) L##str
#define WIDESTR(str) WIDESTR_(str)
int main(int argc, char *argv[])
{
const wchar_t* p = WIDESTR(__FILE__);
wcout << p << endl;
return EXIT_SUCCESS;
}
私のシステムでは、これにより次が生成されます。
/Users/craig/tmp/main/main/test.cpp
最後に...
慰謝料として、この回答のすべてを 1 つの巨大なグーパイルにまとめます。これを行うとどうなると思いますか:
int main()
{
const wchar_t *p = WIDESTR(STRINGIZE(NUM));
wcout << p << endl;
return EXIST_SUCCESS;
}
コードの残りの部分で文字列をどのように使用しますか? 文字列マクロである必要がありますか? 他の値から文字列を作成する標準的な方法は、string.h から sprintf() を使用することです。
#define num 1234
sprintf(string,"%d",num);