Convertir un jeton de préprocesseur en chaîne
-
04-07-2019 - |
Question
Je cherche un moyen de convertir un jeton de préprocesseur en chaîne.
Plus précisément, j'ai quelque part:
#define MAX_LEN 16
et je veux l'utiliser pour éviter le dépassement de la mémoire tampon:
char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);
Je suis ouvert à d'autres méthodes pour réaliser la même chose, mais uniquement pour la bibliothèque standard.
La solution
voir http://www.decompile.com/cpp/faq/file_and_line_error_error_string_html.htm spécifiquement:
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
afin que votre problème puisse être résolu en faisant
sscanf (buf, "%" TOSTRING (MAX_LEN) "s", val);
Autres conseils
J'ai trouvé une réponse en ligne.
#define VERSION_MAJOR 4 #define VERSION_MINOR 47 #define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR
Ce qui précède ne fonctionne pas mais j'espère illustre ce que je voudrais faire, c'est-à-dire que VERSION_STRING se termine comme "v4.47".
Pour générer la forme numérique appropriée utiliser quelque chose comme
#define VERSION_MAJOR 4 #define VERSION_MINOR 47 #define STRINGIZE2(s) #s #define STRINGIZE(s) STRINGIZE2(s) #define VERSION_STRING "v" STRINGIZE(VERSION_MAJOR) \ "." STRINGIZE(VERSION_MINOR) #include <stdio.h> int main() { printf ("%s\n", VERSION_STRING); return 0; }
Cela fait un moment, mais cela devrait fonctionner:
sscanf(buf, "%" #MAX_LEN "s", val);
Si ce n'est pas le cas, vous devrez utiliser une "double extension". astuce:
#define STR1(x) #x
#define STR(x) STR1(x)
sscanf(buf, "%" STR(MAX_LEN) "s", val);
Vous devriez utiliser l'astuce de la macro de développement de chaîne de développement à double expansion. Ou juste avoir un
#define MAX_LEN 16
#define MAX_LEN_S "16"
char val[MAX_LEN+1];
sscanf(buf, "%"MAX_LEN_S"s", val);
et restez synchronisé. (C'est un peu embêtant, mais tant que les définitions sont côte à côte, vous vous en souviendrez probablement.)
En fait, dans ce cas particulier, strncpy
ne serait-il pas suffisant?
strncpy(val, buf, MAX_LEN);
val[MAX_LEN] = '\0';
S'il s'agissait de printf
, ce serait plus simple:
sprintf(buf, "%.*s", MAX_LEN, val);
Bien que certains des "travaux ci-dessus" ci-dessus, je vous recommande d'utiliser une simple API de chaîne de caractères plutôt que le dreck fourni avec libc. Il existe un certain nombre d'API portables, dont certaines sont également optimisées pour faciliter l'inclusion dans votre projet ... et d'autres comme ustr a très peu d'espace disque et supporte les variables de pile.