154 votes

Concaténation de chaînes de macro C / C ++

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

Est-il possible de concaténer ont STR3 == "s1"? Vous pouvez le faire en passant des arguments à une autre fonction Macro. Mais existe-t-il un moyen direct?

193voto

Sean Points 2098

Si ce sont deux chaînes, vous pouvez simplement faire:

 #define STR3 STR1 STR2
 

Le préprocesseur concatène automatiquement les chaînes adjacentes.

MODIFIER:

Comme indiqué ci-dessous, ce n'est pas le préprocesseur mais le compilateur qui effectue la concaténation.

128voto

Jim Balter Points 9250

Vous n'avez pas besoin de ce type de solution pour les littéraux de chaîne, car ils sont concaténés au niveau de la langue. Cela ne fonctionnerait de toute façon pas car "s" "1" n'est pas un jeton valide. Cependant, pour le collage de jetons en général, essayez ceci:

 /*
 * 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)
 

Alors, par exemple, PPCAT(s, 1) produit l'identifiant s1 .

Continuant sur le thème sont ces macros:

 /*
 * 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)
 

Ensuite,

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

26voto

Jordan Brown Points 41

Astuce: L' STRINGIZE macro ci-dessus est cool, mais si vous faites une erreur et son argument n'est pas une macro - vous eu une faute de frappe dans le nom, ou oublié de l' #include le fichier d'en-tête - puis le compilateur sera heureux de mettre à la prétendue nom de la macro dans la chaîne de caractères sans erreur.

Si vous avez l'intention que l'argument d' STRINGIZE est toujours une macro avec un C normale de la valeur, puis

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

permettra d'élargir une fois et vérifier sa validité, à l'écart, puis de l'étendre à nouveau dans une chaîne de caractères.

Il m'a fallu un certain temps à comprendre pourquoi STRINGIZE(ENOENT) a été finissant en "ENOENT" au lieu de "2"... je n'avais pas inclus, errno.h.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X