我写了一个日期函数的日期函数,它返回两个日期的天数(输入格式为20100810)
运行程序后,我的输入字符串被破坏,无法理解我在哪里做错了。
我在AIX上运行它,当我在Redhat上运行它时,字符串没有被破坏。
以下是代码
#include <iostream>
#include <ctime>
#include <sstream>
using namespace std;
int GetYear(std::string dateStr)
{
std::string year = dateStr.substr (0,4);
int sYr = atoi(year.c_str());
//std::cout <<"<<<GetYear dateStr:"<< dateStr << " yearStr:"<< year <<", int sYr:" << sYr << std::endl;
return sYr;
}
int GetMonth(std::string dateStr)
{
//std::cout <<">>>GetMonth dateStr:"<< dateStr << std::endl;
int sMn =0;
std::string mm = dateStr.substr (4,2);
sMn = atoi(mm.c_str());
// std::cout <<"<<<GetMonth dateStr:"<< dateStr <<"MonthStr:"<< mm <<", int MM:" << sMn << std::endl;
return sMn;
}
int GetDay(std::string dateStr)
{
//std::cout << ">>>GetDay dateStr:"<< dateStr << std::endl;
int sDy = 0;
std::string dd = dateStr.substr (6,2);
sDy = atoi(dd.c_str());
//std::cout << "<<<GetDay dateStr:"<< dateStr<<" DayStr:"<< dd <<", int DD:" << sDy << std::endl;
return sDy;
}
int dateDiff_Days (std::string startStr,std::string endStr){
std::cout << ">>>dateDiff_Days" << std::endl;
int sYr;
int eYr;
int sMn;
int eMn;
int sDy;
int eDy;
time_t end;
time_t start;
struct tm *startDate;
struct tm *endDate;
int dif;
int i =0;
//Move over the start date to string and convert string to int
sYr = GetYear(startStr);
sMn = GetMonth(startStr);
sDy = GetDay(startStr);
//Move over the end date to string and convert string to int
eYr = GetYear(endStr);
eMn = GetMonth(endStr);
eDy = GetDay(endStr);
//Move information into startDate structure
start = time(0);
startDate = localtime (&start);
startDate->tm_year = (sYr-1900); //Years since 1900
startDate->tm_mday = sDy; //Day of the month: 1-31
startDate->tm_mon = sMn-1; //Months since Jan: 0-11
//Leave default zero's in for the rest
startDate->tm_sec = '0';
startDate->tm_min = '0';
startDate->tm_hour = '0';
startDate->tm_wday = '0';
startDate->tm_yday = '0';
startDate->tm_isdst = '0';
start = mktime (startDate);
//Move info into endDate structure, same as startDate.
end = time(0);
endDate = localtime (&end);
endDate->tm_year = (eYr-1900);
endDate->tm_mday = eDy;
endDate->tm_mon = eMn-1;
endDate->tm_sec = '0';
endDate->tm_min = '0';
endDate->tm_hour = '0';
endDate->tm_wday = '0';
endDate->tm_yday = '0';
endDate->tm_isdst = '0';
end = mktime (endDate);
dif = difftime (end, start);
dif = dif/86400;
return dif;
}
int main (){
std::string dt1 = "20100810";
std::string dt2 = "20100810";
std::cout << ">>>GetLaterDate before dt1="<< dt1 <<" dt2="<< dt2 << std::endl;
std::string tempDt1 (dt1);
std::string tempDt2 (dt2);
int i = dateDiff_Days(dt1,dt2);
std::cout << ">>>GetLaterDate before dt1="<< dt1 <<" dt2="<< dt2 << std::endl;
std::cout << ">>>GetLaterDate before tempDt1="<< tempDt1 <<" tempDt2="<< tempDt2 << std::endl;
return 0;
}
输出:
>>>GetLaterDate before dt1=20100810 dt2=20100810 >>>dateDiff_Days >>>GetLaterDate before dt1=NULLNULL dt2=NULLNULL >>>GetLaterDate before tempDt1=NULLNULL tempDt2=NULLNULL
答案 0 :(得分:5)
几乎所有初始化tm
结构的行都是错误的,如下所示:
startDate->tm_sec = '0';
这实际上将startDate->tm_sec
设置为48
。字段是整数而不是字符。
答案 1 :(得分:0)
作为旁注,实际上没有必要调用time
和localtime
来获取指向struct tm
的指针,无论如何要覆盖它。你应该这样做:
struct tm ttm;
memset(&ttm, 0, sizeof(ttm));
ttm.tm_year = sYr - 1900;
ttm.tm_mon = sMn - 1;
ttm.tm_mday = sDy;
time_t start = mktime( &ttm );
memset(&ttm, 0, sizeof(ttm)); // Because mktime can alter the struct
ttm.tm_year = eYr - 1900;
ttm.tm_mon = eMn - 1;
ttm.tm_mday = eDy;
time_t end = mktime( &ttm );
我不知道你是否有可能破坏堆,因为localtime
正在返回虚假的东西。也许。试试我在这里给出的东西,至少它是更好的练习,即使它不能解决你的问题。
答案 2 :(得分:0)
localtime和gmtime使用静态分配的struct tm实例。这意味着对它们中任何一个的调用可能会改变其地址(如你所有)保存在另一个指针中的tm值,期望该调用将为您分配一个tm并返回地址。
根据此文档的“返回值”部分(http://www.cplusplus.com/reference/ctime/localtime/)
返回的值指向内部对象,其有效性或 任何后续的gmtime或localtime调用都可能会改变该值。
不是只捕获多个调用返回的地址(每次最多可能相同),而是应该拥有该地址,分配另一个tm并将值复制到该地址。让时间函数像静态实例一样使用。 :)
希望它有所帮助。