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初始化