3.13 调用strptime函数前需初始化tm
代码示例
- int main()
- {
- char* format="%Y-%m-%d %H:%M";//没有秒格式符%S
- char* timeStr="1970-1-1 0:1";//1970年1月1日0时1分,没有秒数
- struct tm time_info;
- if(NULL == strptime(timeStr, format, &time_info)) {
- fprintf(stderr, "error\n");
- }else{
- time_t secondsFrom1970 = timegm(&time_info);//这个值期望是60
- fprintf(stdout, "time =[%s], time in seconds from 1970 is [%d]\n", timeStr, secondsFrom1970);
- }
- return 0;
- }
现象&后果
上述代码运行之后打印出来的并不是期望的60秒。
Bug分析
Linux下man strptime函数可以看到这样一句话,"原则上,这个函数并不会初始化传进来的tm结构,而只是把有指定的字段值存到tm中去。这意味着tm结构需要在调用这个函数之前被初始化"。因此,在调用的strptime时,如果提供的时间字符串不是年月日时分秒都有,并且传递进去的tm结构变量没有被初始化为0,则解析出来的结果是不正确的。
在上述代码中,提供的时间字符串没有秒数,并且没有对tm变量time_info进行初始化,所以运行结果不正确。
正确的做法是,在调用strptime时,要么提供包含"年月日时分秒"的完整时间字符串输入,要么提供的tm结构变量用0初始化。
正确代码
- int main()
- {
- char* format="%Y-%m-%d %H:%M";//没有秒格式符%S
- char* timeStr="1970-1-1 0:1";//1970年1月1日0时1分,没有秒数
- struct tm time_info={0};
- if(NULL == strptime(timeStr, format, &time_info)) {
- fprintf(stderr, "error\n");
- }else{
- time_t secondsFrom1970 = timegm(&time_info);//这个值期望是60
- fprintf(stdout, "time =[%s], time in seconds from 1970 is [%d]\n", timeStr, secondsFrom1970);
- }
- return 0;
- }
编程建议
建议在调用strptime函数时,不管提供的时间字符串是否完整,都对tm结构体用0初始化