web-dev-qa-db-fra.com

Concaténer l'intégralité de la chaîne à l'aide du préprocesseur C

J'essaie de comprendre comment je peux concaténer un #define 'd int à un #define 'd chaîne utilisant le C Préprocesseur. Mon compilateur est GCC 4.1 sur CentOS 5. La solution devrait également fonctionner pour MinGW.

Je voudrais ajouter un numéro de version sur une chaîne, mais la seule façon de le faire fonctionner est de faire une copie du numéro de version défini comme des chaînes.

La chose la plus proche que j'ai pu trouver était une méthode de citation des arguments de macro, mais cela ne fonctionne pas pour #defines

Cela ne fonctionne pas.

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

Cela ne fonctionne pas sans le #s soit parce que les valeurs sont des nombres et il se développerait en "/home/user/.myapp" 2 6, qui n'est pas valide C .

Cela fonctionne, mais je n'aime pas avoir des copies de la version définie car j'en ai aussi besoin de chiffres.

#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
78
jonescb

Question du préprocesseur C classique ....

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

Le niveau supplémentaire d'indirection permettra au préprocesseur d'étendre les macros avant de les convertir en chaînes.

139
Lindydancer

Une méthode de travail consiste à écrire MY_FILE en tant que macro paramétrique:

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

EDIT: Comme indiqué par "Lindydancer", cette solution ne développe pas les macros dans les arguments. Une solution plus générale est:

#define MY_FILE_(x,y) "/home..." #x #y
#define MY_FILE(x,y) MY_FILE_(x,y)
10
Giuseppe Guerrini

Vous pouvez le faire avec 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)
2
Maxim Egorushkin