在C中编译时变量大小的字符串文字

时间:2011-08-26 17:06:03

标签: c string-literals c-preprocessor

DD 应该怎么做?

如果

#define HEADING_TITLE_PROJECT_NAME  "<= Version Maintenance Based On Compiled DateTime =>"
#define SIZE_OF_HEADER_FOR_DECORATION_PURPOSE sizeof(HEADING_TITLE_PROJECT_NAME)
#define DD ????
#define HEADING "\r\n"DD"\r\n"HEADING_TITLE_PROJECT_NAME"\r\n"DD"\r\n"

我想获得 HEADING 字符串文字,如下所示:

<==================================================>
<= Version Maintenance Based On Compiled DateTime =>
<==================================================>

=符号或我放置的任何内容将在&lt; == ... ==&gt;内重复填写 HEADING_TITLE_PROJECT_NAME 空间。

可以这样或其他方式完成。 我只想在编码时更改HEADING_TITLE_PROJECT_NAME,而不是其他任何内容。 只要知道如果可以做到的话 :)

&lt; ==编辑开始==&gt; 像

这样的东西
#define DD\
 char * get()\
{\
    char arr[100] = '\0';\
    for (int i=0; i < SIZE_OF_HEADER_FOR_DECORATION_PURPOSE - 1; i++)\
    {\
        arr[i] = "=";\
    }\  
    return arr;\
}

&lt; ==编辑结束==&gt;

3 个答案:

答案 0 :(得分:3)

不幸的是,在标准C预处理器中没有自动生成DD的方法,只要你想按照HEADING宏定义中的方式使用它。

只要您坚持以HEADING定义它们当前定义的方式,我只能建议使用半自动方法:)。明确地手动定义DD

#define HEADING_TITLE_PROJECT_NAME "<= Version Maintenance Based On Compiled DateTime =>"
#define DD                         "<==================================================>"

然后只需添加

STATIC_ASSERT(sizeof HEADING_TITLE_PROJECT_NAME == sizeof DD);

就在它下面(使用您最喜欢的STATIC_ASSERT实现)。这样,DD长度内的任何差异都会立即触发错误,并迫使开发人员更新DD

答案 1 :(得分:0)

这是不可能的,因为sizeof是在预处理器之后而不是之前评估的。

如果您事先知道字符串的长度,那就是。

因为proprocessor没有任何循环结构,所以你最终会创建它们。 Boost做的就像这样

#define REPEAT_TIMES(macro, n) REPEAT##n(macro)
#define REPEAT1(macro) MACRO
#define REPEAT2(macro) REPEAT1(macro)MACRO
#define REPEAT3(macro) REPEAT2(macro)MACRO
....

然后你就可以了:

#define FILLER "="
#define DD "<"REPEAT_TIMES(FILLER, 34)">"

答案 2 :(得分:-1)

您对DD的实现并不是一个坏主意,尽管它会受到一些不良语法和未定义行为的影响。

const char *DDD(void)
{
    static char arr[] = HEADING_TITLE_PROJECT_NAME;
    if(arr[2] == ' ')
        for(size_t i = 2; i + 3 < sizeof arr; i++)
            arr[i] = '=';
    return arr;
}
#define DD DDD()

您无法返回指向堆栈数据的指针,因此您必须使用static数组。我们可以通过将其自动设置为#define d字符串来确保它是正确的大小,然后检查它是否已被'='填充,如果没有,则填充它。然后我们返回一个const指针,以便没有人试图修改它。

您的宏定义了一个函数get,带有未指定的参数,并返回一个可修改的char *来堆栈数据。不幸的是,这个函数将在你使用宏的任何地方定义,这将导致许多多重定义错误。

你不能将它与原始字符串连接一起使用,但它可以用于你想要的任何其他东西。