打印

C语言的小题目(把项目的编译日期存储在CONST里),请教解答:

[复制链接]
6197|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mcuisp|  楼主 | 2011-6-13 14:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 mcuisp 于 2011-6-13 14:31 编辑

C语言有__DATE__的预定义变量
想把这个日期放进CONST 字符串或数组里,始终不成功。

const char CompileDate[]="__DATE__"。这个写法不行(字符串里就不是日期的数字,而是__DATE__这几个字符:L )。

如何实现如题目的?

相关帖子

沙发
johnwjl| | 2011-6-13 15:29 | 只看该作者
const char CompileDate[] = __DATE__;

使用特权

评论回复
板凳
yewuyi| | 2011-6-13 16:15 | 只看该作者
只见过编译后在MAP文件中显示编译时间的,没见过可以放到CONST的,同求结果,估计无解。

使用特权

评论回复
地板
香水城| | 2011-6-13 16:23 | 只看该作者
这个问题应该是编译器特有的功能,不具有普遍性。

2楼的办法能用吗?

使用特权

评论回复
5
原野之狼| | 2011-6-13 16:36 | 只看该作者
该宏定义的是一个指针  指向编译的时候的时间
所以
加引号是不行的
直接赋值也是不行的 类型都不一致

其实要解决楼主的问题也很简单的啦
该宏和CompileDate就是一个意思
关键看你的代码是如何引用它

使用特权

评论回复
6
原野之狼| | 2011-6-13 17:05 | 只看该作者
本帖最后由 原野之狼 于 2011-6-13 17:29 编辑

我给LZ出个招:
const char *CompileDate=__DATE__;
如果有警告,那就:
const char *CompileDate=(const char *)__DATE__;

以上CompileDate指针内容是可以改变的
如果你的代码不需要改变该指针
那么
#define CompileDate __DATE__
就可以了

如果你的代码还想在内存中缓冲一份可读写的数据
那么
char CompileDate[sizeof(__DATE__) + 1];
然后在程序初始化的时候显式拷贝:
strcpy(CompileDate, __DATE__);

以上第三种方式可能会存在问题,需要实测下。
因为我不清楚__DATE__是数组还是指针,是数组的话就没有问题的。

使用特权

评论回复
7
johnwjl| | 2011-6-13 17:38 | 只看该作者
抄书:
__DATE__包含编译日期的字符串字面值,其形式为 “Mmm dd yyyy“。

使用特权

评论回复
8
hgjinwei| | 2011-6-13 20:01 | 只看该作者
曾今在IAR中这样用过:

/**
*      以下这些宏用于将编译器时间 Mmm dd yyyy hh:mm:ss 转变成 YYMMDDhhmmss 格式
*/
#define SM(o,s,m)               (((o)[0] == (s)[0]) && ((o)[1] == (s)[1]) && (o)[2] == (s)[2]) ? m
#define STRM_TO_BCD(s)          SM("Jan",s,0x01) : SM("Feb",s,0x02) : SM("Mar",s,0x03) : SM("Apr",s,0x04) :\
                                SM("May",s,0x05) : SM("Jun",s,0x06) : SM("Jul",s,0x07) : SM("Aug",s,0x08) :\
                                SM("Sep",s,0x09) : SM("Oct",s,0x10) : SM("Nov",s,0x11) : SM("Dec",s,0x12) : '?'

#define COMPILE_YEAR            STR_TO_BCD(__DATE__ + 9)
#define COMPILE_MON             STRM_TO_BCD(__DATE__+ 0)
#define COMPILE_DAY             STR_TO_BCD(__DATE__ + 4)
#define COMPILE_HOUR            STR_TO_BCD(__TIME__ + 0)
#define COMPILE_MIN             STR_TO_BCD(__TIME__ + 3)
#define COMPILE_SEC             STR_TO_BCD(__TIME__ + 6)

#define COMPILE_TIME            COMPILE_SEC,COMPILE_MIN,COMPILE_HOUR,COMPILE_DAY,COMPILE_MON,COMPILE_YEAR

使用特权

评论回复
9
hgjinwei| | 2011-6-13 20:05 | 只看该作者
然后 const unsigned char CompileTime[] = {COMPILE_TIME};

使用特权

评论回复
10
huangqi412| | 2011-6-13 20:27 | 只看该作者
KEIL中有用过。。。  记得还是从X哥那看的。

使用特权

评论回复
11
mytempid| | 2011-6-14 08:00 | 只看该作者
__DATE__是字符串,编译后已经保存在flash中(即const),可以通过map文件查看绝对地址

我在keil中是类似这样使用:printf("%s", __DATE__)

使用特权

评论回复
12
mcuisp|  楼主 | 2011-6-14 09:30 | 只看该作者
本帖最后由 mcuisp 于 2011-6-14 09:35 编辑

我的目的是想把这个时间,加上其他一些信息放到特定地址。
打个比方:0x8000的地方放字符串:(CopyRight)www.mcuisp.com,2012.12.12. Version 1.000
二楼的方法我试过是可行的,也是正在使用的方法。不足之处是没法和其他信息一起放,只能单独放。

使用特权

评论回复
13
leang521| | 2011-6-14 09:53 | 只看该作者
ANSIC标准定义了以下6种可供C语言使用的预定义宏:   
       __LINE__                        在源代码中插入当前源代码行号   
       __FILE__                        在源代码中插入当前源代码文件名   
       __DATE__                        在源代码中插入当前编译日期〔注意和当前系统日期区别开来〕   
       __TIME__                        在源代码中插入当前编译时间〔注意和当前系统时间区别开来〕         
       __STDC__                        当要求程序严格遵循ANSIC标准时该标识符被赋值为1。   
       __cplusplus   
   标识符__LINE__和__FILE__通常用来调试程序;   
   标识符__DATE__和__TIME__通常用来在编译后的程序中加入一个时间标志,以区分程序的不同版本;

这四个都是预编译宏,不是包含在头文件中的
__FILE__是当前编译的文件的文件名 是一个字符串
__TIME__是当前编译的文件的编译时间 格式是hh:mm:ss 是字符串
__DATE__是当前编译的文件的编译日期 格式是Mmm:dd:yyyy 是字符串
__LINE__是调用该宏语句所在的行数,是个十进制数


用在宏定义中

譬如:
#define TEST (__FILE__" "__TIME__) /*这个括号没有也行的*/
int main(void)
{
printf(TEST);
return 0;
}
假如该代码的文件名叫console.cpp
那么会输出文件名加编译时间
.\console.cpp 21:34:22



但是要注意,因为某些编译器没有严格遵从C99,可能导致此宏无法使用

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
yewuyi + 1 精品文章
14
johnwjl| | 2011-6-14 10:07 | 只看该作者
为什么会不能和其他信息一起放呢?
如:const char information[] = ”(CopyRight)www.mcuisp.com,“__DATE__ “. Version 1.000”

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
yewuyi + 1 精品文章
15
jack_shine| | 2011-6-14 10:22 | 只看该作者
同意9楼的说法,lz试试看

使用特权

评论回复
16
johnwjl| | 2011-6-14 10:31 | 只看该作者
对的,如果需要将日期格式转换,可以用9楼方法。

使用特权

评论回复
17
mcuisp|  楼主 | 2011-6-14 10:35 | 只看该作者
本帖最后由 mcuisp 于 2011-6-14 11:00 编辑

13楼的我试了可行,可惜已经结贴了:)
""的用法不知出于何处,居然如此奇妙(可以连接2个预定义的字符串),呵呵。
14楼的也可行。

万能的21ic,呵呵

使用特权

评论回复
18
原野之狼| | 2011-6-14 10:48 | 只看该作者
我给LZ出个招:
const char *CompileDate=__DATE__;
如果有警告,那就:
const char *CompileDate=(const char *)__DATE__;

以上CompileDate指针内容是可以改变的
如果你的代码不需要改变该指针
那么
#define Compi ...
原野之狼 发表于 2011-6-13 17:05

刚刚自测了一下这个代码 是没有问题的
不过严格来讲 第三种方法中定义数组的大小并不需要再加1

使用特权

评论回复
19
原野之狼| | 2011-6-14 10:52 | 只看该作者
13L和14L的做法很不错 在开源世界里经常能看得见~

使用特权

评论回复
20
huangqi412| | 2011-6-14 10:57 | 只看该作者
这个要MARK

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:www.mcuisp.com 免费STM32 ISP软件 EP968手持烧录器,现场升级/生产线量产STM32,STM8S/L,FreeScale,LPC2000,LPC9xx,C8051F,AVR,PIC......

340

主题

4985

帖子

22

粉丝