0

我写了一个 datediff in days 函数,它返回两个日期的天数(输入格式为 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
4

3 回答 3

6

几乎所有初始化tm结构的行都是错误的,例如:

startDate->tm_sec = '0';

这实际上设置startDate->tm_sec48。这些字段是整数而不是字符

于 2012-09-13T12:32:17.123 回答
1

作为旁注,实际上没有必要调用time并且localtime只是为了获得指向 a 的指针,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返回的东西是虚假的。也许。无论如何尝试我在这里给出的内容,至少它是更好的做法,即使它不能解决你的问题。

于 2012-09-13T22:50:52.820 回答
1

localtime 和 gmtime 使用静态分配的 struct tm 实例。这意味着对它们中的任何一个的调用可能会改变 tm 值,其地址(如您所拥有的)保存在另一个指针中,期望调用将为您分配一个 tm 并返回地址。

根据本文档的“返回值”部分(http://www.cplusplus.com/reference/ctime/localtime/

返回的值指向一个内部对象,其有效性或值可能会被任何后续调用 gmtime 或 localtime 更改。

您应该拥有该地址,分配另一个 tm 并将值复制到该地址,而不是仅捕获对这些函数的多次调用返回的地址(很可能每次都相同)。让时间函数和静态实例一起玩。:)

希望能帮助到你。

于 2016-02-29T13:19:24.133 回答