C 预处理器:用前导零对 int 进行字符串化?

C Preprocessor: Stringify int with leading zeros?

我看到 this topic 描述了 "stringify" 操作:

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

是否可以用前导零进行字符串化?假设我的 MAJOR_REV 在这种情况下需要两个字符“02”和 MINOR_REV 4 个字符“0006” 如果我这样做:

#define MAJOR_VER 02
#define MINOR_VER 0006

这些值将在应用程序的其他地方被视为八进制,这是我不想要的。

没有干净或方便的方法来做到这一点。作为挑战,这里有可能 "solution":

1) 创建一个头文件(例如"smartver.h")包含:

#undef SMARTVER_HELPER_
#undef RESVER
#if VER < 10
#define SMARTVER_HELPER_(x) 000 ## x
#elif VER < 100
#define SMARTVER_HELPER_(x) 00 ## x
#elif VER < 1000
#define SMARTVER_HELPER_(x) 0 ## x
#else
#define SMARTVER_HELPER_(x) x
#endif
#define RESVER(x) SMARTVER_HELPER_(x)

2) 在您的源代码中,任何需要带前导零的版本号的地方:

#undef VER
#define VER ...your version number...
#include "smartver.h"

此时,表达式RESVER(VER)被扩展为一个四位字符序列,表达式STR(RESVER(VER))是等效的字符串(注意:我使用了您发布的STR宏在你的回答中)。

前面的代码与您的示例中的次要版本的大小写相匹配,修改它以匹配 "major version" 的大小写是微不足道的。但实际上我会使用一个简单的外部工具来生成所需的字符串。

我相信问题 sprintf 提供的示例是正确答案。

也就是说,在某些情况下您确实想要这样做,并且如果有意愿并且有人愚蠢到可以编写代码,那么通常有办法使用 C 预处理器。

我编写了宏 FORMAT_3_ZERO(a),它使用暴力创建了一个三位零填充数字。它位于 https://gist.github.com/lod/cd4c710053e0aeb67281158bfe85aeef 的文件 preprocessor_format_zero.h 中,因为它太大太丑无法内联。

用法示例

#include "preprocessor_format_zero.h"

#define CONCAT_(a,b) a#b
#define CONCAT(a,b) CONCAT_(a,b)

#define CUSTOM_PACK(a) cp_ ## a __attribute__( \
        (section(CONCAT(".cpack.", FORMAT_3_ZERO(a))), \
        aligned(1), used))

const int CUSTOM_PACK(23);