2015-02-17 71 views
4

我见过this topic它做介绍了“字符串”操作:C预处理器:用前导零对字符串int进行处理?

#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 

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

+2

我的直觉是这将是足够的硬度,即使升压::预处理器,它是不是真的值得做。将“MAJOR_VER_STR”和“MINOR_VER_STR”定义为带前导零的字符串。你可以创建一个脚本来设置主版本和次版本以及匹配的字符串:'setversion --major = 2 --minor = 7 header.h'这个工作。 – 2015-02-17 21:39:20

+0

它可以用Boost.Preprocessor完成,但我相信你必须配合“插槽”才能做到这一点。如果初始数字格式不同,如主版本10的'#define MAJOR_VER(1)(0)',则可以更简单地完成。 – 2015-02-18 01:49:38

+3

您是否需要使用预处理器?你不能为它编写常规的C代码吗?对不起,如果这是一个愚蠢的问题。 – 2015-02-18 09:27:39

回答

6

没有干净,也没有方便的方法来做到这一点。正如一个挑战,在这里一个可能的“解决方案”:含

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宏在你回答)。

前面的代码与您示例中次版本的大小写匹配,修改它以匹配“主要版本”大小写并不重要。但事实上,我会用一个简单的外部工具来生成所需的字符串。

0

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

这就是说,有一些情况下你真的想这样做,并用C预处理器,如果有一个愿意和有人愚蠢,写代码通常是一种方式。

我写了宏FORMAT_3_ZERO(a),它使用蛮力创建了一个三位零填充数字。它位于文件preprocessor_format_zero.h中,在https://gist.github.com/lod/cd4c710053e0aeb67281158bfe85aeef处找到,因为它太大而且难以内联。

用法示例

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