使用时间函数后,字符串被破坏

时间:2012-09-13 12:27:58

标签: c++ string datetime

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

3 个答案:

答案 0 :(得分:5)

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

startDate->tm_sec = '0';

这实际上将startDate->tm_sec设置为48。字段是整数而不是字符

答案 1 :(得分:0)

作为旁注,实际上没有必要调用timelocaltime来获取指向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并将值复制到该地址。让时间函数像静态实例一样使用。 :)

希望它有所帮助。