2009-09-06 10 views
8

Ich brauche Hilfe Sie folgendermaßen vorgehen: #Wie wird ein Pfund/Hash über C-Präprozessor gedruckt?

ein Präprozessormakro Etikett (x) wird ausgegeben "#x", zB

#define label(x) ... 

wenn ich Etikett nennen (aname), wird der Ausgang sein“ aname "(ohne Anführungszeichen)

Ich weiß, dass die folgenden Versuche Fehler waren.

#define label(x) #x // leads to "x" 
#define label(x) \#x // is \"x" 
#define label(x) "#x" // is "#x" (but not the content of x") "#otto" 

Es kann eine Art entkam # (Raute) existieren, aber ich weiß nicht, wie zu entkommen ...

bearbeiten: I „gcc -E Test -o Test ausführen .html ", um die Ausgabe zu erhalten. Der Punkt ist: Wie drucke ich ein Hash-Zeichen (#) mit einem Makro nur mit Präprozessor-Fähigkeiten?

+1

Darf ich fragen, was Sie versuchen zu tun? –

+0

* g * ja. Ich werde den Präprozessor verwenden, um HTML-Code zu erstellen;) label (x) soll verwendet werden, um eine Verbindung zu einem Anker zu erstellen, z. B. ... Ich reduzierte die Komplexität für die Frage. – tuergeist

+0

Möchten Sie diesen HTML-Code als Zeichenfolge, für die Verwendung in einem C-Programm oder als tatsächlichen HTML-Code, um direkt zum Browser zu gelangen? –

Antwort

13

Die Antwort ist:

#define hash # 
#define f(x) x 
#define label(a) f(hash)a 

dann

label(foobar) 

schafft

#foobar 

Ich fand es mit Hilfe von Sie alle, aber vor allem Wintermute. Vielen Dank!

(Mit gcc 4.3.3)

+0

aber das ist keine Antwort auf Ihre Frage: Sie fragte nach dem zitierten Ausdruck '" #foobar "' – Christoph

+0

Ist das gut definiert, oder eine Funktion der spezifischen Präprozessor-Implementierung tuergeist verwendet? – bdonlan

+0

Ich möchte nur sagen, dass du eines Tages vielleicht wiederkommen und eine andere Frage stellen wirst, wie du den C-Präprozessor dazu bringen kannst, X oder Y zu machen. Ich hoffe, du wirst dich daran erinnern, was ich über diesen schweren Kampf gesagt habe und dass Sie meine Empfehlung, ein neues Tool für diesen Job zu finden, in Betracht ziehen. –

1

Versuchen:

#define label(x) "#"x 
+0

nur ok wenn als char * in c verwendet – tuergeist

3

Stringliterale in C verkettet werden, so können Sie dies tun

#define label(x) "#" #x 

Ich glaube nicht, es ohne String-Verkettung möglich ist (dh ohne den C-Compiler den Aufruf als Sie wollen tun):

Sie können einige ausgefallene Dinge mit zusätzlichen Ebenen der Indirektion und ich habe sogar den Präprozessor, um die gewünschte Ausgabe über

zu generieren
#define hash # 
#define quote(x) #x 
#define in_between(c, d) quote(C## d) 
#define join(c, d) in_between(c, d) 
#define label(x) join(hash, x) 
label(foo) 

Das Problem ist, es wird auch eine Fehlermeldung wie in_between() zu #foo erweitert, die keine gültigen Präprozessor-Token sind. Ich sehe das nicht anders.

Mein Ratschlag wäre, das richtige Werkzeug für den Job zu wählen: Wechseln Sie zu einer anderen Makrosprache wie m4 oder sogar ML/I, wenn Sie abenteuerlustig sind oder eine Skriptsprache wie PHP oder Perl verwenden. GPP scheint auch gut und könnte eine bessere Passform sein.

+0

führt zu '' # '' string '' das ist nicht '#string' darf ich fragen, wie haben Sie Ihre Antwort getestet? – tuergeist

+0

In der C-Sprache schreiben wir 'char * c =" # "" string ";' ist identisch mit dem Schreiben von 'char * c =" #string ";' - die Sprache verkettet Zeichenkettenliterale, die nebeneinander liegen. Dies funktioniert also nicht mit dem Präprozessor zusammen, sondern funktioniert mit der C-Sprache. –

+0

Wie ich geschrieben habe, verwende ich die Ausgabe des Präprozessors, kein zusätzlicher c-Compiler wird ausgeführt. – tuergeist

4

Ich glaube nicht, dass Sie können, was nicht völlig unvernünftig ist, da die Ausgabe des C-Präprozessors kein nicht angekreuztes '#' erzeugen sollte, da dies eine Präprozessor-Direktive anzeigen würde, und Sie keine Präprozessor-Anweisungen generieren können im laufenden Betrieb so.

Mit anderen Worten, der C-Präprozessor ist ein Präprozessor für C (und C++) und kein Allzweckwerkzeug.

Entweder verwenden Sie einen alternativen Makroprozessor (m4 ist die Standardempfehlung für Unix-ähnliche Systeme), oder gehen Sie die Dinge anders.

Zum Beispiel haben den Makro Ersatz: '! @'

#define label(x) [email protected]!x 

Dann nachbearbeiten die Ausgabe ersetzt mit '#'. Das Programmverwendet einen ähnlichen Trick, der C-Präprozessor erledigt die meiste Arbeit, aber seine Ausgabe behält keine Zeilenumbrüche bei, die von 'make' benötigt werden, also verwendet 'imake' die Schreibweise '@@ \' oder um anzuzeigen, wo Zeilenumbrüche eingefügt werden müssen, nachdem der C-Präprozessor sein schlechtestes getan hat.)

+0

Vielen Dank für Ihren Vorschlag ... – tuergeist

+0

+1 für das Denken über den Tellerrand – nalply

4

Sie können etwas tun:

#define f(x) x 
#define label(a) f(#)a 

Getestet habe ich diese, indem sie es direkt durch cpp (der C-Präprozessor) statt durch gcc läuft. Beispiel:

cpp test > test.html 

Verwendung der cpp, die Teil der GCC-Version 4.0.1 ist.

Das einzige Problem, das ich bemerkte, dass ich einig zusätzlichen unerwünschten Ausgang, nämlich die ersten 4 Zeilen der Datei erhalten sind wie folgt:

# 1 "test" 
# 1 "<built-in>" 
# 1 "<command line>" 
# 1 "test" 
+0

2:16: Fehler: '#' ist nicht gefolgt von einem Makro-Parameter – tuergeist

+0

@ tuergeist - Ich habe es tatsächlich etwas anders getestet als du. Siehe meinen aktualisierten Beitrag. –

+0

diese erste Zeile sind ok und können ignoriert werden. – tuergeist

Verwandte Themen