2011-03-28 10 views
57

Próbuję dowiedzieć się, w jaki sposób można złączyć się #define „d int do #define” ciąg d pomocą C preprocesora. Mój kompilator to GCC 4.1 na CentOS 5. Rozwiązanie powinno również działać dla MinGW.Łączy int na ciąg przy użyciu C preprocesor

Chciałbym dołączyć numer wersji na sznurku, ale tylko w ten sposób mogę zmusić go do pracy jest, aby kopia numeru wersji określa jako ciągi.

Najbliższy rzeczą mogłyby znaleźć był sposób przytoczyć argumenty makr, ale to nie działa dla #define s

To jest nie działa.

#define MAJOR_VER 2 
#define MINOR_VER 6 
#define MY_FILE "/home/user/.myapp" #MAJOR_VER #MINOR_VER 

To nie działa bez # s albo ponieważ wartości są liczbami i byłoby rozszerzyć do "/home/user/.myapp" 2 6, który nie jest ważny C.

To działa, ale nie lubię posiadające kopie wersji definiuje bo trzeba je jako numery, jak również.

#define MAJOR_VER 2 
#define MINOR_VER 6 
#define MAJOR_VER_STR "2" 
#define MINOR_VER_STR "6" 
#define MY_FILE "/home/user/.myapp" MAJOR_VER_STRING MINOR_VER_STRING 
+3

Możliwy duplikat [Konwersja tokenu preprocesora na ciąg] (http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string) –

Odpowiedz

97

Klasyczny C preprocesor pytanie ....

#define STR_HELPER(x) #x 
#define STR(x) STR_HELPER(x) 

#define MAJOR_VER 2 
#define MINOR_VER 6 
#define MY_FILE "/home/user/.myapp" STR(MAJOR_VER) STR(MINOR_VER) 

Dodatkowy poziom zadnie pozwoli rozszerzyć preprocesora makra przed są konwertowane na ciągi.

+2

Dzięki. To działa i jest to bardzo czyste rozwiązanie. – jonescb

+0

STR() w tym przypadku da ci Wąski łańcuch. Czy istnieje wariacja do konwersji tego na szeroki ciąg? – gkns

2

można zrobić z BOOST_PP_STRINGIZE:

#define MAJOR_VER 2 
#define MINOR_VER 6 
#define MY_FILE "/home/user/.myapp" BOOST_PP_STRINGIZE(MAJOR_VER) BOOST_PP_STRINGIZE(MINOR_VER) 
+20

Uśmiecha mnie uśmieszek, jak ludzie rzucają doładowanie we wszystkim. –

+4

@Frerich: Przyjmowanie argument ekstremalnych, ludzie powinni pisać własne kompilatory pierwszy surowca kodu maszynowego, zamiast rzucania g ++ na wszystko ... nie ma sensu wyważać otwartych drzwi. Dobrzy programiści piszą kod, wspaniale wykorzystują. –

+0

@jonescb: właśnie otwarty [nagłówek impuls] (http://svn.boost.org/svn/boost/trunk/boost/preprocessor/stringize.hpp) i przekonaj się sam. –

8

Sposób pracy jest napisanie my_file postaci parametrycznej makro:

#define MY_FILE(x,y) "/home..." #x #y 

EDIT: Jak zauważył „Lindydancer”, to rozwiązanie nie rozszerza makr w argumentach. Bardziej ogólne rozwiązanie:

#define MY_FILE_(x,y) "/home..." #x #y 
#define MY_FILE(x,y) MY_FILE_(x,y) 
+1

W mojej uczciwej opinii jest to najlepsza odpowiedź i jest znacznie prostsza niż inne sugestie. Jestem zaskoczony, że nie dostałem lepszej oceny! – osirisgothra

+3

To czyste rozwiązanie, które niestety nie działa. Jeśli argument przekazany do 'MY_FILE' to makra, powiedz" A "i" B ", to makro rozwinie się do' "/ home ..." "A" "B" '. – Lindydancer

+1

Prawidłowo, ale jest dobrze znane obejście (patrz edycja). –