Come stringificare la macro con array come #define a_macro {5,7,7,97}?

Per favore, passa attraverso

#define _VERSION_ 1.4 #define DEFAULT_NETWORK_TOKEN_KEY { 3, 6, 5, 100} 

// Non riesco a modificare i macro precedenti ma di seguito

 #define STR_VALUE(arg) #arg #define FUNCTION_NAME(name) STR_VALUE(name\r) #define TEST_FUNC #AP started v _VERSION_ #define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC) #define QUOTE_X(t)#t #define QUOTE(t)QUOTE_X(t) #define ABC 100 //{ 3, 6, 5, 100} #define MYSTR "The value of ABC is" const uint8 startMsg[] = MYSTR " " QUOTE(ABC); 

risultati: il valore di ABC è 100

 const uint8 startMsg[] = TEST_FUNC_NAME; 

risultati: #AP avviato v 1.4 (ritorno a capo ) // Voglio anche rimuovere lo spazio tra v e 1.4

Voglio

 const uint8 startMsg[] = ?? ; 

Il risultato dovrebbe essere #AP avviato [3.6.5.100] v1.4 (ritorno a capo ) o #AP avviato [3,6,5,100] v1.4 (ritorno a capo ) o simile.

Sto lavorando su un chip SOC e ho bisogno di mostrarlo all’avvio. Urgente. 🙂

—— La risposta alla domanda è ——

 #define NETTOKENKEY(a,b,c,d) "[" #a "." #b "." #c "." #d "]" #define GENNETTOKENKEY(z) NETTOKENKEY(z) #define STRINGIZER(arg) #arg #define STR_VALUE(arg) STRINGIZER(arg) #define AP_VERSION_STR "#AP started v" STR_VALUE(_VERSION_) #define AP_NETVERSION_STR "#AP started " \ GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES) \ " v" STR_VALUE(_VERSION_) **"\r"** const uint8 startMsg[] = AP_NETVERSION_STR ; 

Il Preprocessore C è un programma di sostituzione del testo abbastanza semplice, e non penso che sarà in grado di fare ciò che ti serve e produrre stringhe costanti in fase di compilazione se è assolutamente imansible cambiare la macro DEFAULT_NETWORK_TOKEN_KEY .

Trasformare la notazione ‘array’ è particolarmente difficile – in effetti, la precondizione di non cambiare la matrice che definisce la macro probabilmente significa che è imansible.

Se è ansible definire nuove macro e ridefinire DEFAULT_NETWORK_TOKEN_KEY modo che produca lo stesso valore di sempre, è ansible ottenere il risultato desiderato.

Per illustrare, nota che puoi scrivere:

 #define x { 3, 45, 5, 49} #define f4(a,b,c,d) #a " - " #b ":" #c "/" #d #define y(z) f4(z) y(x) 

Quando pre-elaborato, ciò produce:

 "{ 3" " - " "45" ":" "5" "/" "49}" 

Nota che le parentesi sono parti delle stringhe degli argomenti. Ora, se puoi fare:

 #define DEFAULT_NETWORK_TOKEN_KEY_VALUES 3, 6, 5, 100 #define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_VALUES} 

(dove sto preservando la tua spaziatura asimmetrica, anche se non penso che sia davvero necessario), allora puoi usare:

 #define NETTOKENKEY(a,b,c,d) "[" #a "." #b "." #c "." #d "]" #define GENNETTOKENKEY(z) NETTOKENKEY(z) GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES) 

per ottenere la stringa “[3.6.5.100]” (per i valori nel mio esempio).

Liberarsi dello spazio tra la v e la 1.4 è relativamente facile:

 #define STRINGIZER(arg) #arg #define STR_VALUE(arg) STRINGIZER(arg) #define AP_VERSION_STR "#AP started v" STR_VALUE(_VERSION_) AP_VERSION_STR 

Mettendo insieme questi elementi si ottiene:

 #define AP_NETVERSION_STR "#AP started " \ GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES) \ " v" STR_VALUE(_VERSION_) static const char version[] = AP_NETVERSION_STR; 

Se si desidera un '\r' alla fine, aggiungere "\r" alla fine della definizione della macro AP_NETVERSION_STR. La concatenazione di stringhe è molto utile!

Ma questo si basa sulla possibilità di “cambiare” la definizione di DEFAULT_NETWORK_TOKEN_KEY modo che sia suscettibile di essere formattata in questo modo. Senza questo cambiamento, non penso che tu possa farlo.


Il test è necessario!

 #define _VERSION_ 1.4 #define DEFAULT_NETWORK_TOKEN_KEY_VALUES 3, 6, 5, 100 #define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_VALUES} #define NETTOKENKEY(a,b,c,d) "[" #a "." #b "." #c "." #d "]" #define GENNETTOKENKEY(z) NETTOKENKEY(z) GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES) #define STRINGIZER(arg) #arg #define STR_VALUE(arg) STRINGIZER(arg) #define AP_VERSION_STR "#AP started v" STR_VALUE(_VERSION_) AP_VERSION_STR #define AP_NETVERSION_STR "#AP started " \ GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES) \ " v" STR_VALUE(_VERSION_) AP_NETVERSION_STR 

Quando si esegue gcc -E , l’output leggermente igienizzato (le righe vuote e i controlli #line rimossi) è ciò di cui abbiamo bisogno:

 "[" "3" "." "6" "." "5" "." "100" "]" "#AP started v" "1.4" "#AP started " "[" "3" "." "6" "." "5" "." "100" "]" " v" "1.4" 

perché usare la macro se puoi:

 uint arr[] = DEFAULT_NETWORK_TOKEN_KEY; float v = VERSION; sprintf(buffer, "#AP started [%u.%u.%u.%u] v%f", arr[0], arr[1], arr[2], arr[3], v); 

Leggi informazioni su # e ## nel preprocessore C. Stai mettendo molto involucro attorno a qualcosa di abbastanza facile

http://gcc.gnu.org/onlinedocs/cpp/Stringification.html

A proposito, AFAIK non sarà in grado di utilizzare il preprocessore per trasformare il tuo {} in []

È meglio utilizzare una struttura dati preprocessore come fornita da Boost.Preprocessor . Tutti i macro funzionano in C89 standard.