74

I'm looking for a way to convert a preprocessor token to a string.

Specifically, I've somewhere got:

#define MAX_LEN 16

and I want to use it to prevent buffer overrun:

char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);

I'm open to other ways to accomplish the same thing, but standard library only.

4

6 に答える 6

121

具体的には、 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", val);

于 2008-10-27T15:47:38.133 に答える
24

I found an answer online.

#define VERSION_MAJOR 4
#define VERSION_MINOR 47

#define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR

The above does not work but hopefully illustrates what I would like to do, i.e. make VERSION_STRING end up as "v4.47".

To generate the proper numeric form use something like

#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;
}
于 2008-10-27T15:45:33.443 に答える
7

しばらく経ちましたが、これはうまくいくはずです:

 sscanf(buf, "%" #MAX_LEN "s", val);

そうでない場合は、「二重展開」トリックが必要です。

 #define STR1(x)  #x
 #define STR(x)  STR1(x)
 sscanf(buf, "%" STR(MAX_LEN) "s", val);
于 2008-10-27T15:46:45.703 に答える
3

二重展開文字列化マクロ トリックを使用する必要があります。またはただ持っている

#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);
于 2008-10-27T20:32:57.870 に答える
1

上記の「動作」の一部は、個人的には、libc に含まれるドレックの代わりに単純な文字列 API を使用することをお勧めします。いくつかの移植可能な API があり、その中にはプロジェクトに簡単に組み込めるように最適化されているものもあります。また、ustrのようなものは、スペースのオーバーヘッドが小さく、スタック変数をサポートしています。

于 2008-10-28T14:59:16.407 に答える