Utilisation du préprocesseur C pour construire un littéral de chaîne pour scanf?

J’essaie de créer un littéral de chaîne sscanf pour aider à la prévention de dépassement de mémoire tampon dans C99. Le but est quelque chose comme:

 #define MAX_ARG_LEN 16 char arg[MAX_ARG_LEN] = ""; if (sscanf(arg, "%"(MAX_ARG_LEN-1)"X", &input) > 0) 

La solution “manuelle” évidente est quelque chose comme:

 #define MAX_ARG_LEN 16 #define MAX_ARG_CHARS "15" char arg[MAX_ARG_LEN] = ""; if (sscanf(arg, "%"MAX_ARG_CHARS"X", &input) > 0) 

Cependant, je préférerais que quelque chose génère automatiquement “% 15X” étant donné une taille de tampon de 16. Ce lien fonctionne presque pour mon application: Convertir un jeton de préprocesseur en chaîne mais il ne gère pas le -1.

Suggestions?

Kernighan et Pike discutent de cette question dans leur (excellent) ouvrage intitulé ” La pratique de la programmation ” et concluent que la méthode la plus fiable et la plus portable consiste à utiliser sprintf() pour générer la chaîne de format.

Ce que vous pouvez faire est de définir la macro comme longueur excluant terminal null, puis l’utiliser comme ceci:

 #define STR_EVALUATE(x) #x #define STRINGIFY(x) STR_EVALUATE(x) #define MAX_ARG_LEN 15 char arg[MAX_ARG_LEN+1] = ""; if (sscanf(arg, "%" STRINGIFY(MAX_ARG_LEN) "X", &input) > 0) ... 

Vous pouvez également définir MAX_ARG_STRLEN sur 15 et MAX_ARG_LEN sur MAX_ARG_STRLEN + 1 et travailler en conséquence.