プリプロセッサトークンを文字列に変換します
-
04-07-2019 - |
質問
プリプロセッサトークンを文字列に変換する方法を探しています。
具体的には、どこかにあります:
#define MAX_LEN 16
そしてバッファオーバーランを防ぐためにそれを使いたい:
char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);
同じことを達成するために他の方法を受け入れていますが、標準ライブラリのみです。
解決
http://www.decompile.com/cpp/faq/file_and_line_error_string.htmを参照してください。 具体的には:
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
そうすることで問題を解決できます
sscanf(buf、"%" TOSTRING(MAX_LEN)" s&quot ;, val);
他のヒント
オンラインで回答を見つけました。
#define VERSION_MAJOR 4 #define VERSION_MINOR 47 #define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR
上記は機能しませんが、うまくいけば 私がやりたいことを示しています つまり、VERSION_STRINGが最終的に " v4.47"。
適切な数値形式を生成するには 次のようなものを使用します
#define VERSION_MAJOR 4 #define VERSION_MINOR 47 #define STRINGIZE2(s) #s #define STRINGIZE(s) STRINGIZE2(s) #define VERSION_STRING "v" STRINGIZE(VERSION_MAJOR) \ "." STRINGIZE(VERSION_MINOR) #include <stdio.h> int main() { printf ("%s\n", VERSION_STRING); return 0; }
しばらく経ちましたが、これでうまくいくはずです:
sscanf(buf, "%" #MAX_LEN "s", val);
そうでない場合は、「二重展開」する必要があります。トリック:
#define STR1(x) #x
#define STR(x) STR1(x)
sscanf(buf, "%" STR(MAX_LEN) "s", val);
二重拡張文字列化マクロトリックを使用する必要があります。または、
#define MAX_LEN 16
#define MAX_LEN_S "16"
char val[MAX_LEN+1];
sscanf(buf, "%"MAX_LEN_S"s", val);
そして同期を保ちます。 (それは少し面倒ですが、定義が互いに隣り合っている限り、おそらく覚えているでしょう。)
実際には、この特定のケースでは、 strncpy
では十分ではありませんか?
strncpy(val, buf, MAX_LEN);
val[MAX_LEN] = '\0';
ただし、 printf
の場合、これは簡単です。
sprintf(buf, "%.*s", MAX_LEN, val);
上記の「作業」の一部ですが、個人的には、libcに付属するドレックの代わりに単純な文字列APIを使用することをお勧めします。いくつかのポータブルAPIがあり、その中にはプロジェクトへの組み込みを容易にするために最適化されたものもあります... ustr には小さなスペースオーバーヘッドがあり、スタック変数をサポートしています。