Convertire un token del preprocessore in una stringa

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.