2009-09-06 10 views
8

Potrzebuję pomocy w następujący sposób:Jak wydrukować funt/hash przez preprocesor C?

etykietę preprocesora makro (x) jest wyjście "#x", np

#define label(x) ... 

jeśli zadzwonię etykietę (ÁNazwy), wyjście będzie „# aname "(bez cytatów)

Wiem, że następujące próby były błędami.

#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" 

może istnieć rodzaj uciekł # (funt), ale nie wiem, jak uciec ...

Edit: biegnę „test TEST gcc -E -o .html ", aby uzyskać dane wyjściowe. Chodzi o to: Jak wydrukować znak krzyżyka (#) za pomocą maku tylko przy użyciu możliwości preprocesora?

+1

Czy mogę zapytać, co próbujesz zrobić? –

+0

* g * tak. Użyję preprocesora do "utworzenia" kodu html;) do stworzenia łącza do kotwicy użyjemy etykiety (x) , np. ... Zredukuje to złożoność pytania. – tuergeist

+0

Czy chcesz, aby ten kod HTML był łańcuchem znaków, używany w programie C lub jako rzeczywisty kod HTML, aby przejść bezpośrednio do przeglądarki? –

Odpowiedz

13

Odpowiedź brzmi:

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

następnie

label(foobar) 

tworzy

#foobar 

Znalazłem go przy pomocy was wszystkich, ale szczególnie zimowy. Wielkie dzięki!

(Korzystanie z gcc 4.3.3)

+0

ale to nie jest odpowiedź na twoje pytanie: prosiłeś o cytowane wyrażenie ''#foobar" ' – Christoph

+0

Czy jest to dobrze zdefiniowane, czy funkcja specyficznego procesora sterującego procesem wstępnym? – bdonlan

+0

Chcę tylko powiedzieć, że pewnego dnia może się zdarzyć, że wrócicie tutaj i zadać kolejne pytanie o to, jak uzyskać preprocesor C do wykonania X lub Y. Mam nadzieję, że zapamiętacie, co powiedziałem o tym, że jest to ciężka bitwa oraz, że zdecydowanie rozważasz moją rekomendację znalezienia nowego narzędzia do tej pracy. –

1

Spróbuj:

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

tylko ok, jeśli używany jako znak * w c – tuergeist

3

literały łańcuchowe w C będą łączone, dzięki czemu można zrobić

#define label(x) "#" #x 

Nie sądzę, że to możliwe bez łańcuchów znaków (czyli bez odwoływania się do kompilatora C jako chcesz to zrobić):

Możesz zrobić kilka fantazyjnych rzeczy z dodatkowymi poziomami pośrednimi i nawet dostałem preprocesor do wygenerowania pożądanego wyjścia przez

#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) 

Problemem jest to także generuje komunikat o błędzie, jak in_between() rozszerza się #foo, który nie jest ważny tokenu preprocesora. Nie widzę tego w żaden sposób.

Moja rada to wybór odpowiedniego narzędzia do pracy: przełącz się na inny język makr, np. M4 lub nawet ML/I, jeśli czujesz się na siłach lub użyj języka skryptowego, takiego jak PHP lub Perl. GPP wydaje się również niezły i może być lepiej dopasowany.

+0

prowadzi do "" "" ciąg "", który nie jest "#string" czy mogę zapytać, jak przetestowałeś swoją odpowiedź? – tuergeist

+0

W języku C, pisanie 'char * c =" # "" string ";' jest identyczne z zapisem 'char * c =" #string ";' - język łączy literały łańcuchowe, które są obok siebie. Tak więc nie działa to razem z preprocesorem, ale działa z językiem C. –

+0

Tak jak napisałem, użyję wyjścia preprocesora, nie uruchomię żadnego dodatkowego kompilatora c. – tuergeist

4

Nie sądzę, można, co nie jest całkowicie nieuzasadnione, ponieważ wyjście C preprocesor nie powinien produkować niecytowany „#”, ponieważ to byłoby wskazać dyrektywę preprocesora i nie może generować dyrektyw preprocesora w locie w ten sposób.

Innymi słowy, preprocesor C jest preprocesorem dla C (i C++), a nie narzędziem całkowicie ogólnego przeznaczenia.

Użyj alternatywnego procesora makr (m4 to standardowe zalecenie w systemach uniksowych) lub inaczej rozwiązuj różne kwestie.

Na przykład, mają makro Zamiennik: '! @'

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

Następnie po procesie wyjście zastępując z '#'.

Program wykorzystuje podobną sztuczkę, preprocesor C wykonuje większość pracy, ale jej wyniki nie zachowują podziałów linii wymaganych przez "make", więc "imake" używa notacji "@@" lub w pobliżu, aby wskazać, gdzie należy wstawić podziały wierszy po tym, jak preprocesor C zrobił najgorsze.)

+0

Dziękuję za sugestię ... – tuergeist

+0

+1 za myślenie nieszablonowe – nalply

4

można zrobić coś takiego:

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

testowałem to poprzez uruchomienie go bezpośrednio poprzez cpp (C preprocesora) zamiast przez gcc. Przykład:

cpp test > test.html 

Korzystanie z cpp, który jest częścią wersji gcc 4.0.1.

Jedyny problem jaki zauważyłem jest to, że mogę dostać dodatkowe niechciane wyjście, mianowicie pierwsze 4 linie pliku są następujące:

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

2:16: błąd: po '#' nie występuje parametr makro – tuergeist

+0

@ tuergeist - faktycznie testowałem to trochę inaczej niż ty. Zobacz mój zaktualizowany wpis. –

+0

te pierwsze linie są w porządku i można je zignorować. – tuergeist