仅从日期宏中提取年份

Extract only year from date macro

本文关键字:提取 取年份 日期      更新时间:2023-10-16

我的问题类似于__DATE__宏的不同格式但上面提到的解决方案在我的VS2013编译器中显示了错误。

我只想从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],'' };

但是,我再次无法在CYC宏中使用它。只使用宏而不使用任何变量真的不可能实现这一点吗?

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

#include <stdio.h>
int main(void) {
const char *build_year = __DATE__ + 7;
printf("This program was compiled in %sn", 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 %sn", CYC);
return 0;
}

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

使用以下代码怎么样:

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("%sn", 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], ' ', ''}, COMPANY)

或更灵活的

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