#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 y a-t-il un moyen direct?
c++
c
c-preprocessor
tvr
la source
la source
Réponses:
Si ce sont les deux chaînes, vous pouvez simplement faire:
Le préprocesseur concatène automatiquement les chaînes adjacentes.
ÉDITER:
Comme indiqué ci-dessous, ce n'est pas le préprocesseur mais le compilateur qui effectue la concaténation.
la source
L"a"
et"b"
obtenirL"ab"
, mais vous pouvez concaténerL"a"
etL"b"
obtenirL"ab"
.Vous n'avez pas besoin de ce genre de solution pour les chaînes littérales, puisqu'elles sont concaténées au niveau de la langue, et cela ne fonctionnerait pas de toute façon parce que "s" "1" n'est pas un jeton de préprocesseur valide.
[Edit: En réponse au commentaire incorrect "Juste pour mémoire" ci-dessous qui a malheureusement reçu plusieurs votes positifs, je vais réitérer la déclaration ci-dessus et observer que le fragment de programme
produit ce message d'erreur à partir de la phase de prétraitement de gcc: error: coller "" s "" et "" 1 "" ne donne pas un jeton de prétraitement valide
]
Cependant, pour le collage général de jetons, essayez ceci:
Ensuite, par exemple, les deux
PPCAT_NX(s, 1)
etPPCAT(s, 1)
produisent l'identifiants1
, sauf s'ils
est défini comme une macro, auquel casPPCAT(s, 1)
produit<macro value of s>1
.Continuant sur le thème sont ces macros:
Ensuite,
Par contre,
la source
"s""1"
est valide en C (et C ++). Ce sont deux jetons (littéraux de chaîne) que le compilateur concatre et menace comme un seul jeton."s""1" isn't a valid token
- c'est exact; il s'agit, comme vous le dites, de deux jetons. Mais les assembler avec ## en ferait un seul jeton de prétraitement, pas deux jetons, et ainsi le compilateur ne ferait pas de concaténation, mais plutôt le lexeur les rejetterait (le langage nécessite un diagnostic).STRINGIZE_NX(whatever occurs here)
S'étend donc à "tout ce qui se passe ici", quelles que soient les définitions de macro pour ce qui se passe ou ici.if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"
- c'est faux et cela n'a rien à voir avec votre test. Vous vous efforcez de ne pas comprendre ou de ne pas comprendre cela correctement, et je ne vais pas vous répondre davantage.Astuce: La
STRINGIZE
macro ci-dessus est cool, mais si vous faites une erreur et que son argument n'est pas une macro - vous avez eu une faute de frappe dans le nom, ou vous avez oublié#include
le fichier d'en-tête - alors le compilateur mettra volontiers le nom de la macro dans le chaîne sans erreur.Si vous souhaitez que l'argument de
STRINGIZE
soit toujours une macro avec une valeur C normale, alorsle développera une fois et vérifiera sa validité, le rejettera, puis le développera à nouveau en une chaîne.
Il m'a fallu un certain temps pour comprendre pourquoi
STRINGIZE(ENOENT)
finissait comme"ENOENT"
au lieu de"2"
... je n'avais pas incluserrno.h
.la source
,
opérateur. :)((1),"1") "." ((2),"2")
au lieu de seulement "1" "." "2")STRINGIZE
définition originale ,"The value of ENOENT is " STRINGIZE(ENOENT)
fonctionne, alors que"The value of ENOENT is" STRINGIZE_EXPR(X)
produit une erreur.