Wenn Sie nur mit String-Literalen arbeiten, können Sie einfach Strings verwenden. Wenn Sie ein String-Literal nach dem anderen platzieren, verkettet der Compiler diese.
Wenn möglicherweise andere Dinge als String-Literale beteiligt sind (z. B. wenn Sie neue Bezeichner aus den Makros erstellen), verwenden Sie die Option „##“Operator zum Einfügen von Präprozessor-Tokens. Sie müssten wahrscheinlich auch den ‘#‘ ‘Stringisierungsoperator, um Ihre Makros in Literalzeichenfolgen umzuwandeln.
Ein Beispiel für #1:
#ifdef __TESTING
#define IV_DOMAIN "example.org" // In house testing
#elif __LIVE_TESTING
#define IV_DOMAIN "test.example.com" // Live testing servers
#else
#define IV_DOMAIN "example.com" // Production
#endif
// Subdomain
#define IV_SECURE "secure." IV_DOMAIN // secure.example.org, etc.
#define IV_MOBILE "m." IV_DOMAIN
Und was den Token-Paste-Operator betrifft, glaube ich nicht, dass die meisten Antworten, die die Verwendung des Token-Paste-Präprozessoroperators vorgeschlagen haben, ihn tatsächlich ausprobiert haben – die Verwendung kann schwierig sein.
Die Verwendung der häufig vorgeschlagenen Antwort führt zu einem Compilerfehler, wenn Sie versuchen, die zu verwenden IV_SECURE Makro, weil:
#define IV_SECURE "secure."##IV_DOMAIN
erweitert sich zu:
"secure"example.org
Vielleicht möchten Sie versuchen, das zu verwenden '#`’ ‘Stringisierungs’-Operator:
#define IV_SECURE "secure." #IV_DOMAIN
Aber das wird nicht funktionieren, weil es nur mit Makroargumenten funktioniert – nicht mit irgendeinem alten Makro.
Wenn Sie die Vorverarbeitungsoperatoren token-paste (‘##’) oder stringizing (‘#’) verwenden, sollten Sie sich darüber im Klaren sein, dass Sie eine zusätzliche Indirektionsebene verwenden müssen, damit sie in allen Fällen ordnungsgemäß funktionieren.
Wenn Sie dies nicht tun und die an den Token-Einfüge-Operator übergebenen Elemente selbst Makros sind, erhalten Sie Ergebnisse, die wahrscheinlich nicht Ihren Wünschen entsprechen:
#include <stdio.h>
#define STRINGIFY2( x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#define PASTE2( a, b) a##b
#define PASTE( a, b) PASTE2( a, b)
#define BAD_PASTE(x,y) x##y
#define BAD_STRINGIFY(x) #x
#define SOME_MACRO function_name
int main()
{
printf( "buggy results:\n");
printf( "%s\n", STRINGIFY( BAD_PASTE( SOME_MACRO, __LINE__)));
printf( "%s\n", BAD_STRINGIFY( BAD_PASTE( SOME_MACRO, __LINE__)));
printf( "%s\n", BAD_STRINGIFY( PASTE( SOME_MACRO, __LINE__)));
printf( "\n" "desired result:\n");
printf( "%s\n", STRINGIFY( PASTE( SOME_MACRO, __LINE__)));
}
Verwenden Sie also Ihr Original IV_DOMAIN Definiert und die Dienstprogrammmakros von oben, können Sie Folgendes tun, um das zu bekommen, was Sie wollen:
Ich sehe viele gute und richtige Antworten auf Ihre erste Frage, aber keine auf Ihre zweite. Deshalb hier: Ich halte das für eine schreckliche Idee.
Warum sollten Sie Ihre Software (insbesondere die Release-Version) neu erstellen müssen, nur um den Servernamen zu ändern? Und woher wissen Sie, welche Version Ihrer Software auf welchen Server verweist? Sie müssen einen Mechanismus zur Überprüfung zur Laufzeit einbauen.
Wenn es auf Ihrer Plattform überhaupt praktikabel ist, empfehle ich Ihnen, die Domains/URLs aus einer Konfigurationsdatei zu laden. Nur die kleinsten eingebetteten Plattformen sind für diesen Zweck möglicherweise nicht „praktisch“ 🙂
Versuchen Sie es mit dem ##-Operator
#define IV_SECURE secure.##IV_DOMAIN
Ich glaube, das OP hat nach der Zeichenfolgenverkettung (#) und nicht nach dem Einfügen von Token (##) gefragt. Ich habe jedoch nicht abgelehnt. Die Frage ist etwas zweideutig.
– e.James
28. April 2009 um 14:38
Das Einfügen von Token (‘##’) oder das Stringisieren (‘#’) funktioniert ohne einige zusätzliche Dinge nicht.
– Michael Burr
28. April 2009 um 15:01 Uhr
Peter Mortensen
Was Sie benötigen, sind die Operatoren # und ## sowie eine automatische Zeichenfolgenverkettung.
Der Vorverarbeitungsoperator # wandelt den Makroparameter in eine Zeichenfolge um. Der ##-Operator fügt zwei Token (z. B. Makroparameter) zusammen.
Dies wird automatisch zu „secure.domain.org“ verkettet (vorausgesetzt, die Phasen der Übersetzung sind in C und C++ dieselben).
Bitte, bitte lesen Sie die Kommentare, die zeigen, wie ich es geschafft habe, verwirrt zu sein. Bedenken Sie, dass ich in C durchaus erfahren bin, wenn auch vielleicht etwas eingerostet. Ich würde diese Antwort löschen, aber ich dachte, ich würde sie als Beispiel dafür belassen, wie leicht es ist, vom C-Präprozessor verwirrt zu werden.
Ich glaube, das OP hat nach der Zeichenfolgenverkettung (#) und nicht nach dem Einfügen von Token (##) gefragt. Ich habe jedoch nicht abgelehnt. Die Frage ist etwas zweideutig.
– e.James
28. April 2009 um 14:38
Das Einfügen von Token (‘##’) oder das Stringisieren (‘#’) funktioniert ohne einige zusätzliche Dinge nicht.
– Michael Burr
28. April 2009 um 15:01 Uhr
Wie andere angemerkt haben, verwenden Sie das Einfügen von Token. Sie sollten sich auch darüber im Klaren sein, dass Makronamen wie
__TESTING
sind in C (ich kenne Objective C nicht) für die Implementierung reserviert – Sie dürfen sie nicht in Ihrem eigenen Code verwenden. Die reservierten Namen sind alles, was doppelte Unterstriche enthält und alles, was mit einem Unterstrich und einem Großbuchstaben beginnt.
Ziel C soll eine strikte Obermenge von C sein, daher sollte dies ein gültiger Hinweis sein.
– Chris Lutz
28. April 2009 um 14:48
14541900cookie-checkMakros zum Erstellen von Strings in Cyes
Mögliches Duplikat von Konvertieren eines Präprozessor-Tokens in eine Zeichenfolge
– Ciro Santilli OurBigBook.com
5. Okt. 2015 um 13:33