Sto cercando un modo per convertire un token del preprocessore in una stringa.
In particolare, ho capito da qualche parte:
#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 la libreria standard.
vedere 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);
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 che illustri ciò che vorrei fare, cioè rendere VERSION_STRING come “v4.47”.
Per generare il modulo numerico appropriato usa qualcosa di simile
#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
int main() { printf ("%s\n", VERSION_STRING); return 0; }
È passato un po ‘di tempo, ma dovrebbe funzionare:
sscanf(buf, "%" #MAX_LEN "s", val);
In caso contrario, sarà necessario un trucco “doppia espansione”:
#define STR1(x) #x #define STR(x) STR1(x) sscanf(buf, "%" STR(MAX_LEN) "s", val);
Dovresti usare il trucco della macro per la specificazione della 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 tienilo sincronizzato. (Questo è un po ‘fastidioso, ma finché le definizioni sono l’una accanto all’altra probabilmente te ne ricorderai.)
In realtà, in questo caso particolare, non sarebbe strncpy
?
strncpy(val, buf, MAX_LEN); val[MAX_LEN] = '\0';
Se fosse printf
, però, sarebbe più semplice:
sprintf(buf, "%.*s", MAX_LEN, val);
Mentre alcuni dei suddetti “funzionano”, personalmente raccomanderei semplicemente di usare una semplice API per le stringhe invece del dreck che è contenuto in libc. Esistono numerose API portatili, alcune delle quali sono ottimizzate per facilitare l’inclusione nel tuo progetto … e alcuni come ustr hanno un sovraccarico di spazio ridotto e supporto per le variabili dello stack.