Converti un token preprocessore in una stringa
-
04-07-2019 - |
Domanda
Sto cercando un modo per convertire un token preprocessore in una stringa.
In particolare, da qualche parte ho:
#define MAX_LEN 16
e voglio usarlo per prevenire il sovraccarico del buffer:
char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);
Sono aperto ad altri modi per realizzare la stessa cosa, ma solo libreria standard.
Soluzione
vedi http://www.decompile.com/cpp/faq/file_and_line_error_string.htm in particolare:
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
quindi il tuo problema può essere risolto facendo
sscanf (buf, "% " TOSTRING (MAX_LEN) " s " ;, val);
Altri suggerimenti
Ho trovato una risposta online.
#define VERSION_MAJOR 4 #define VERSION_MINOR 47 #define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR
Quanto sopra non funziona ma si spera illustra cosa mi piacerebbe fare ovvero fare in modo che VERSION_STRING finisca come & Quot; v4.47 ".
Per generare la forma numerica corretta usa qualcosa come
#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; }
È passato del tempo, ma dovrebbe funzionare:
sscanf(buf, "%" #MAX_LEN "s", val);
In caso contrario, dovrà essere "doppia espansione". trucco:
#define STR1(x) #x
#define STR(x) STR1(x)
sscanf(buf, "%" STR(MAX_LEN) "s", val);
Dovresti usare il trucco macro di stringificazione a doppia espansione. O semplicemente avere un
#define MAX_LEN 16
#define MAX_LEN_S "16"
char val[MAX_LEN+1];
sscanf(buf, "%"MAX_LEN_S"s", val);
e mantienilo sincronizzato. (È un po 'fastidioso, ma finché le definizioni sono una accanto all'altra, probabilmente ti ricorderai.)
In realtà, in questo caso particolare, strncpy
è sufficiente?
strncpy(val, buf, MAX_LEN);
val[MAX_LEN] = '\0';
Se fosse printf
, tuttavia, sarebbe più semplice:
sprintf(buf, "%.*s", MAX_LEN, val);
Mentre alcuni dei precedenti "funzionano", personalmente consiglierei semplicemente di usare una semplice API stringa invece del dreck che viene fornito in libc. Esistono numerose API portatili, alcune delle quali sono anche ottimizzate per facilitare l'inclusione nel progetto ... e altre come ustr ha un sovraccarico di spazio ridotto e supporto per le variabili dello stack.