#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
Ist es möglich, STR3 == "s1" zu verketten? Sie können dies tun, indem Sie Argumente an eine andere Makrofunktion übergeben. Aber gibt es einen direkten Weg?
c++
c
c-preprocessor
tvr
quelle
quelle
Antworten:
Wenn beide Zeichenfolgen sind, können Sie einfach Folgendes tun:
Der Präprozessor verkettet automatisch benachbarte Zeichenfolgen.
BEARBEITEN:
Wie unten erwähnt, ist es nicht der Präprozessor, sondern der Compiler, der die Verkettung vornimmt.
quelle
L"a"
und"b"
bekommenL"ab"
, aber man kann verkettenL"a"
undL"b"
bekommenL"ab"
.Sie benötigen diese Art von Lösung für Zeichenfolgenliterale nicht, da sie auf Sprachebene verkettet sind und es sowieso nicht funktionieren würde, da "s" "1" kein gültiges Präprozessor-Token ist.
[Bearbeiten: Als Antwort auf den falschen Kommentar "Nur für den Datensatz" unten, der leider mehrere positive Stimmen erhalten hat, werde ich die obige Aussage wiederholen und feststellen, dass das Programm fragmentiert ist
erzeugt diese Fehlermeldung aus der Vorverarbeitungsphase von gcc: error: Das Einfügen von "" s "" und "" 1 "" ergibt kein gültiges Vorverarbeitungstoken
]]
Versuchen Sie jedoch für das allgemeine Einfügen von Token Folgendes:
Dann zB beide
PPCAT_NX(s, 1)
undPPCAT(s, 1)
erzeugen den Bezeichners1
, sofern nichts
als Makro definiert, in welchem FallPPCAT(s, 1)
erzeugt wird<macro value of s>1
.Weiter zum Thema sind diese Makros:
Dann,
Im Gegensatz,
quelle
"s""1"
ist in C (und C ++) gültig. Dies sind zwei Token (String-Literale), die der Compiler selbst zusammenfassen und als ein Token bedrohen würde."s""1" isn't a valid token
- das ist richtig; Es sind, wie Sie sagen, zwei Token. Wenn Sie sie jedoch zusammen mit ## anheften, werden sie zu einem einzigen Vorverarbeitungstoken, nicht zu zwei Token, und der Compiler führt keine Verkettung durch, sondern der Lexer lehnt sie ab (die Sprache erfordert eine Diagnose).STRINGIZE_NX(whatever occurs here)
sich also zu "was auch immer hier vorkommt", unabhängig von Makrodefinitionen für was auch immer, vorkommt oder hier.if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"
- das ist falsch und nichts mit Ihrem Test zu tun. Sie bemühen sich, dies nicht zu verstehen oder richtig zu machen, und ich werde Ihnen nicht weiter antworten.Hinweis: Das
STRINGIZE
obige Makro ist cool, aber wenn Sie einen Fehler machen und sein Argument kein Makro ist - Sie hatten einen Tippfehler im Namen oder haben#include
die Header-Datei vergessen -, fügt der Compiler den angeblichen Makronamen gerne in das ein Zeichenfolge ohne Fehler.Wenn Sie beabsichtigen, dass das Argument to
STRINGIZE
immer ein Makro mit einem normalen C-Wert ist, dannwird es einmal erweitern und auf Gültigkeit prüfen, verwerfen und dann erneut zu einer Zeichenfolge erweitern.
Es dauerte eine Weile, um herauszufinden , warum
STRINGIZE(ENOENT)
wurde enden wie"ENOENT"
statt"2"
... Ich hatte nicht im Preis enthaltenerrno.h
.quelle
,
Bedieners. :)((1),"1") "." ((2),"2")
statt nur "1". "" 2 "führt)STRINGIZE
Definition"The value of ENOENT is " STRINGIZE(ENOENT)
funktioniert, während"The value of ENOENT is" STRINGIZE_EXPR(X)
ein Fehler erzeugt.