【问题标题】:Compile time variable sized string literal in C在 C 中编译时间可变大小的字符串文字
【发布时间】:2011-08-26 17:06:03
【问题描述】:

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 =>
<==================================================>

= 符号或我曾经输入的任何内容将在 内重复以填充 HEADING_TITLE_PROJECT_NAME 空间。

可以这样或其他方式完成。 我只想在编码时更改 HEADING_TITLE_PROJECT_NAME,其他没有。 只是想如果它可以完成 :)

#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;\
}

【问题讨论】:

    标签: c string-literals c-preprocessor


    【解决方案1】:

    不幸的是,在标准 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

    【讨论】:

    • 最后这是我唯一的选择.. \m/
    【解决方案2】:

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

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

    因为前处理器没有任何循环结构,所以您最终会创建它们。 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)">"
    

    【讨论】:

      【解决方案3】:

      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 数组。我们可以通过将其自动设置为#defined 字符串来确保它的大小正确,然后检查它是否已经被'=' 填充,如果没有,则填充它。然后我们返回一个const 指向它的指针,这样就没有人试图修改它了。

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

      您不能将它与原始字符串连接一起使用,但它可以用于您想要的所有其他内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-15
        • 2021-11-18
        • 1970-01-01
        相关资源
        最近更新 更多