Cプリプロセッサを使用してintを文字列に連結


90

Cプリプロセッサを使用して、#define'd intを#define' d文字列に連結する方法を理解しようとしています。私のコンパイラはCentOS 5上のGCC 4.1です。このソリューションはMinGWでも機能するはずです。

文字列にバージョン番号を追加したいのですが、それを機能させる唯一の方法は、バージョン番号の定義を文字列としてコピーすることです。

私が見つけた最も近いものはマクロ引数を引用する方法でしたが、それは#defines では機能しません

これは機能しません。

#define MAJOR_VER 2
#define MINOR_VER 6
#define MY_FILE "/home/user/.myapp" #MAJOR_VER #MINOR_VER

#値が数値であり、に展開されるため、sがなければ機能しません。"/home/user/.myapp" 2 6これは有効なCではありません。

これは機能しますが、バージョン定義のコピーを番号としても必要とするので、私はバージョン定義のコピーが好きではありません。

#define MAJOR_VER 2
#define MINOR_VER 6
#define MAJOR_VER_STR "2"
#define MINOR_VER_STR "6"
#define MY_FILE "/home/user/.myapp" MAJOR_VER_STRING MINOR_VER_STRING

回答:


168

古典的なCプリプロセッサの質問...

#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

#define MAJOR_VER 2
#define MINOR_VER 6
#define MY_FILE "/home/user/.myapp" STR(MAJOR_VER) STR(MINOR_VER)

追加レベルの間接参照により、プリプロセッサは、マクロが文字列に変換される前にマクロを展開できます。


3
この場合のSTR()は、狭い文字列を提供します。これをワイド文字列に変換するバリエーションはありますか?
gkns


'#'はマクロ引数でのみ機能するため、最初の "STR_HELPER"が必要です。それを理解する
のに少し時間

@clarkttfu、一種の-はい、#マクロ引数でのみ機能します。ただし、STR_HELPERマクロMAJOR_VERを文字列"MAJOR_VAR"に変換しないようにするために、マクロが必要です"2"
Lindydancer

12

効果的な方法は、MY_FILEをパラメトリックマクロとして書き込むことです。

#define MY_FILE(x,y) "/home..." #x #y

編集:「リンディダンサー」で述べたように、このソリューションは引数のマクロを展開しません。より一般的な解決策は次のとおりです。

#define MY_FILE_(x,y) "/home..." #x #y
#define MY_FILE(x,y) MY_FILE_(x,y)

1
私の正直な意見では、これが最良の答えであり、他の提案よりもはるかに単純です。良い評価が得られなかったことに驚いています!
osirisgothra 2013年

5
これは、残念ながら機能しないクリーンなソリューションです。渡される引数MY_FILEがマクロである場合、たとえばAとするとB、このマクロはに展開され"/home..." "A" "B"ます。
Lindydancer 2014

2

あなたはBOOST_PP_STRINGIZEでそれを行うことができます:

#define MAJOR_VER 2
#define MINOR_VER 6
#define MY_FILE "/home/user/.myapp" BOOST_PP_STRINGIZE(MAJOR_VER) BOOST_PP_STRINGIZE(MINOR_VER)

28
人々がすべてでブーストを投げる方法を私ににやにや笑わせます。
Frerich Raabe、2011

4
@Frerich:議論を極端にすると、人々はすべての場所でg ++をスローするのではなく、生のマシンコードで最初に独自のコンパイラを書く必要があります...車輪を再発明する意味はありません。優れたプログラマはコードを書き、優れたプログラマは再利用します。
Maxim Egorushkin、2011年

@jonescb:ブーストヘッダーを開い確認してください。
Maxim Egorushkin 2011年

10
うん、やってみた。うまくいきましたが、CプログラムでBoostヘッダーを使用するのは、ちょっと奇妙に思えます。
jonescb

1
ああ、私の悪い、Cタグに気づかなかった。
Maxim Egorushkin、2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.