Concatenazione di macro stringhe C / C ++

#define STR1 "s" #define STR2 "1" #define STR3 STR1 ## STR2 

E ‘ansible concatenare avere STR3 == “s1”? Puoi farlo passando gli argomenti ad un’altra funzione Macro. Ma c’è un modo diretto?

Se sono entrambe le stringhe, puoi semplicemente fare:

 #define STR3 STR1 STR2 

Il preprocessore concatena automaticamente le stringhe adiacenti.

MODIFICARE:

Come indicato di seguito, non è il preprocessore ma il compilatore che esegue la concatenazione.

Non è necessario questo tipo di soluzione per i letterali stringa, poiché sono concatenati a livello di lingua e non funzionerebbe comunque perché “s” “1” non è un token di preprocessore valido. Tuttavia, per l’incollaggio generico di token, prova questo:

 /* * Concatenate preprocessor tokens A and B without expanding macro definitions * (however, if invoked from a macro, macro arguments are expanded). */ #define PPCAT_NX(A, B) A ## B /* * Concatenate preprocessor tokens A and B after macro-expanding them. */ #define PPCAT(A, B) PPCAT_NX(A, B) 

Quindi, ad esempio, PPCAT(s, 1) produce l’identificatore s1 .

Continuando sul tema sono queste macro:

 /* * Turn A into a string literal without expanding macro definitions * (however, if invoked from a macro, macro arguments are expanded). */ #define STRINGIZE_NX(A) #A /* * Turn A into a string literal after macro-expanding it. */ #define STRINGIZE(A) STRINGIZE_NX(A) 

Poi,

 #define T1 s #define T2 1 STRINGIZE(PPCAT(T1, T2)) // produces "s1" 

Suggerimento: la macro STRINGIZE sopra è interessante, ma se fai un errore e il suo argomento non è una macro – hai avuto un refuso nel nome, o hai dimenticato di #include il file header – allora il compilatore metterà felicemente in pratica la macro presunta nome nella stringa senza errori.

Se si intende che l’argomento di STRINGIZE sia sempre una macro con un valore C normale, quindi

 #define STRINGIZE(A) ((A),STRINGIZE_NX(A)) 

lo espanderò una volta e lo controllerà per validità, lo scarto e quindi lo espanderò di nuovo in una stringa.

Mi ci è voluto un po ‘per capire perché STRINGIZE(ENOENT) stava finendo come "ENOENT" invece di "2" … Non avevo incluso errno.h .