仅从日期宏中提取年份

时间:2017-01-27 16:31:05

标签: c++ c visual-studio macros c-preprocessor

我的问题类似于Different format of __DATE__ macro 但是那里提到的解决方案在我的VS 2013编译器中显示错误。

我想从 date 宏中取出年份部分,以便创建一个包含

字符串的宏
#define BUILD_YEAR_CH0 (__DATE__[ 7])
#define BUILD_YEAR_CH1 (__DATE__[ 8])
#define BUILD_YEAR_CH2 (__DATE__[ 9])
#define BUILD_YEAR_CH3 (__DATE__[ 10])

#define COPY "Copyright"

#define COMPANY "ABCD Lmtd"

#define CYC BUILD_YEAR_CH0 BUILD_YEAR_CH1 BUILD_YEAR_CH2 COMPANY

这样我就可以使用CYC宏在需要的地方打印连接字符串。

但是一旦我在CYC宏中使用BUILD_YEAR_CH0宏/令牌,它就会显示错误。

我也试过制作一个const char缓冲区,它具有完整的年份值,如

const char MYEAR[] = { __DATE__[7], __DATE__[8],__DATE__[9],__DATE__[10],'\0' };

但同样,我无法在CYC宏中使用它。 是否真的不可能只用宏来完成这个,而不是使用任何变量?

2 个答案:

答案 0 :(得分:1)

__DATE__宏扩展为格式为"Mmm dd yyyy"的11字节字符串文字。您可以初始化一个字符串指针,指向该文字的第8个字节,稍后可以将其用作4字节的C字符串,其中包含编译日期的年份部分。该指针可以是本地或全局的,具有自动或静态存储:

#include <stdio.h>

int main(void) {
    const char *build_year = __DATE__ + 7;

    printf("This program was compiled in %s\n", build_year);
    return 0;
}

你甚至可以在宏中使用这种方法:

#define BUILD_YEAR  (__DATE__ + 7)

注意:

    使用clang编译上述代码时,
  • -Weverything会发出警告:

    ctyear.c:4:37: warning: expansion of date or time macro is not reproducible [-Wdate-time]
    

    您可以使用-Wno-date-time停用此警告。

  • 不幸的是,此方法无法用于__DATE__宏的其他部分。

编辑:您还可以在Makefile中定义宏。使用此方法,您可以完全控制要在扩展中包含的字段:

ctyear: ctyear.c
    clang '-DBUILD_YEAR="$(shell date +%Y)"' $< -o $@

<强> ctyear.c

#include <stdio.h>

#define COMPANY  "Newco"
#define CYC BUILD_YEAR " " COMPANY

int main(void) {
    printf("Copyright %s\n", CYC);
    return 0;
}

如果你有一个包含许多源文件的大项目,你可能有一个Makefile,你可以将'-DBUILD_YEAR="$(shell date +%Y)"'添加到CFLAGS的定义中。

答案 1 :(得分:0)

使用此代码怎么样:

main.c中:

#include <stdio.h>

#define STRINGIFY(s) # s
#define EXPAND(s) STRINGIFY(s)

#define COMPANY "ABCD Lmtd"
#define CYC EXPAND(MYEAR) " "  COMPANY

int main(void)
{
  printf("%s\n", CYC);
}

像这样编译:

gcc -Wall -Wextra -pedantic -Wconversion -g main.c -o main -DMYEAR=$(date +"%Y")

打印

2017 ABCD Lmtd

虽然我不明白为什么你关心日期如果它最终以宏形式出现,这是使用__DATE__宏的另一种方法:

#define CYC strcat((char[4 + 1 + 1 + sizeof COMPANY]){__DATE__[7], __DATE__[8], __DATE__[9], __DATE__[10], ' ', '\0'}, COMPANY)

或更灵活

#define CYC(s) strcat((char[4 + 1 + 1 + sizeof (s)]){__DATE__[7], __DATE__[8], __DATE__[9], __DATE__[10], ' ', '\0'}, s)