4

定義済みの C 値を組み合わせて文字列を生成するにはどうすればよいですか。

#define APP_NUMBER 22
#define ICON_FILE  "../icons/"##APP_NUMBER##".ico"

私の.rcファイルで次のことができるように

 1000 ICON  ICON_FILE

1000 アイコンの代わりに「../icons/22.ico」

うまくいきませんでした

  #define MY_ICON_FILE 25
  #define STR(x) #x
  #define ICON_FILE_NUM(x) "../icons/" STR(x) ".ico"
  1000 ICON  ICON_FILE_NUM(MY_ICON_FILE)

コンパイラ エラー

  can't open icon file `../icons/': Permission denied

  nothing was appended to "../icons/"

私が得た最も近いものは、これを行うことでした:

  #define MY_ICON_FILE 25
  #define STR(x) #x
  #define ICON_FILE_NUM(x) "../icons/"STR(x)".ico" /// took out spaces
  1000 ICON  ICON_FILE_NUM(MY_ICON_FILE)

( STR(x) の周りのスペースを取り出します )

このコンパイラエラーが発生しました

 can't open icon file `../icons/"25".ico': Invalid argument
4

4 に答える 4

4

これは機能します:

#define APP_NUMBER 22
#define STR(x) #x
#define ICON_FILE_NAME(num)  "../icons/" STR(num) ".ico"
#define ICON_FILE ICON_FILE_NAME(APP_NUMBER)

#include <stdio.h>
int main(void) {
    printf("ICON_FILE = \"%s\"\n", ICON_FILE);
    return 0;
}

出力は次のとおりです。

ICON_FILE = "../icons/22.ico"

ただし、ICON_FILEマクロはに展開されます。これはCの有効な構文です(隣接する文字列リテラルは連結されます)が、表示される「アイコンファイルを開けません」というメッセージを説明するファイルの場合は"../icons/" "22" ".ico"おそらくそうではありません。.rc

トークン貼り付けを使用して文字列リテラルを生成しようとしているようです。それに関する問題は、一致しない文字を含む部分的な文字列リテラル"が有効な前処理トークンになることができないことです。たとえば"、マクロへの引数としてシングルを渡すことはできません。

#define適切なディレクティブを生成するプログラム(スクリプトなど)を作成することを検討してください。

于 2012-11-22T06:09:23.947 に答える
1

Windows リソース ファイルは、ほとんどの要素の C スタイル リテラル文字列連結を認識しません。文字列テーブルは唯一の例外かもしれません。

プリプロセッサ マクロを操作するときの秘訣は、入力の開始点として文字列を使用しないことです。プリプロセッサは引用符を削除する方法を知りません。

"-I../icons/"また、一度だけ連結することも役立ちます。リソース名にパスを追加するのではなく、検索パスを追加することを検討してください。

私がほとんどの場所で見たものよりも追加のレベルの間接化を使用しているWindows msvcを使用した例です。

#    define BOOST_PP_CAT(a, b) BOOST_PP_CAT_OO((a, b))
#    define BOOST_PP_CAT_OO(par) BOOST_PP_CAT_I ## par
#    define BOOST_PP_CAT_I(a, b) a ## b

#    define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_A((text))
#    define BOOST_PP_STRINGIZE_A(arg) BOOST_PP_STRINGIZE_I arg
#    define BOOST_PP_STRINGIZE_I(text) #text

例では、実行できるようです BOOST_PP_CAT(../icons/, BOOST_PP_CAT(num,.ico))

外側の CAT のみが適用される文字列化に渡す問題があります (少なくとも Windows では)。だから うまくいきBOOST_PP_STRINGIZE(BOOST_PP_CAT(../icons/, BOOST_PP_CAT(num,.ico)))ません。

3項目連結加算

#    define BOOST_PP_CAT2(a, b, c) BOOST_PP_CAT_OO2((a, b, c))
#    define BOOST_PP_CAT_OO2(par) BOOST_PP_CAT_I2 ## par
#    define BOOST_PP_CAT_I2(a, b, c) a ## b ## c

私のVS2013のテストでは、

  • .."..."相対パスで作業するように変換されていますdifficult
  • \\\マクロ引数で動作するようにエスケープする必要がありますが、に変換されています"\\"-/パスを使用するとよりうまく機能します

アイコンを操作するよりも、文字列テーブルを操作する方が出力を確認しやすい場合があります

STRINGTABLE
BEGIN
  123  BOOST_PP_STRINGIZE(BOOST_PP_CAT(APP_NUMBER, .ico))
  124  BOOST_PP_STRINGIZE(BOOST_PP_CAT2(../icons/, APP_NUMBER,.ico)))
END

.. に変換されることの解決策はまだ解決していません... 追加の検索パスを使用して次の作業を行いました。

1000        ICON        BOOST_PP_STRINGIZE(BOOST_PP_CAT(APP_NUMBER, .ico))
1001        ICON        BOOST_PP_STRINGIZE(BOOST_PP_CAT2(icons/, APP_NUMBER, .ico))
于 2015-09-30T22:22:02.293 に答える
-1

Cプリプロセッサではできないと思います。ただし、m4プリプロセッサを使用してそれを行うことができます。

linux_prompt> cat icon.m4
define(APP_NUMBER, 22)

1000 ICON "../icons/APP_NUMBER.ico"

linux_prompt> m4 icon.m4

1000 ICON "../icons/22.icon"

ファイルの残りの部分が正しく展開されていることを確認する必要があります。詳細については、「manm4」を実行してください。

于 2012-11-23T21:51:51.807 に答える
-1

正直なところ、プリプロセッサを使用してこれを行うことは避けたいと思います。プリプロセッサ エラーのデバッグは骨の折れる作業であり、プリプロセッサの置換と連結の複数のレイヤーが使用され、問題を見つけようとすると大惨事になるケースを見てきました。ちょうど私の2セント。

于 2012-11-22T15:05:16.763 に答える