==本行最终类别==
这不是std::ostringstream
的问题,我用"time.h"
做了一些我不太了解的坏事。最初的问题出现在课后。最后一堂课如下:
timestamp.h
#ifndef __TIMESTAMP_H
#define __TIMESTAMP_H
#include <string>
#include "time.h"
class CTimestamp {
private:
std::string timestamp;
time_t rawtime;
struct tm errorTime;
struct tm tempTime;
bool quality;
public:
CTimestamp();
void set(std::string inputTime);
std::string get();
std::string get(int modifiedBy);
bool good();
void getWeekday(); // Mainly for testing purposes - if this returns
// the correct weekday for your modified timestamp,
// you probably modified it correctly.
};
#endif
timestamp.cpp
#include "timestamp.h"
#include "time.h"
#include <string>
#include <stdlib.h>
#include <iostream>
#include <sstream>
CTimestamp::CTimestamp(){
quality = 0;
}
void CTimestamp::set(std::string inputTime){
quality = 1;
int year, month, day, hour, minute, second;
if (19 == inputTime.length()){
inputTime.replace(10,1," ");
inputTime.replace(13,1,":");
inputTime.replace(16,1,":");
year = atoi(inputTime.substr(0,4).c_str());
month = atoi(inputTime.substr(5,2).c_str());
day = atoi(inputTime.substr(8,2).c_str());
hour = atoi(inputTime.substr(11,2).c_str());
minute = atoi(inputTime.substr(14,2).c_str());
second = atoi(inputTime.substr(17,2).c_str());
timestamp = inputTime;
}
else{
quality = 0;
}
if(quality){
// Get current time with the "time_t time(struct tm * timeptr)" function from time.h
time(&rawtime);
// Change to local time with "struct tm * localtime (const time_t * timer)" function from time.h
errorTime = *localtime(&rawtime);
// Change to the time of the timestamp
errorTime.tm_year = year - 1900; //Years since 1900
errorTime.tm_mon = month - 1; //Months since january
errorTime.tm_mday = day; //Day of the month
errorTime.tm_hour = hour; //Hours since midnight
errorTime.tm_min = minute; //minutes since hour
errorTime.tm_sec = second; //Seconds since minute
// modifies errorTime so overflows in lower units increment higher units then sets tm_wday and tm_yday
mktime ( &errorTime );
}
}
void CTimestamp::getWeekday(){
const char * weekday[] = {"sun", "mon", "tue", "wed", "thu", "fri", "sat"};
std::cout << weekday[errorTime.tm_wday];
}
std::string CTimestamp::get(){
std::string returnValue = "Bad Initialization";
if(quality){
returnValue = timestamp;
}
return returnValue;
}
std::string CTimestamp::get(int modifiedBy){
std::string returnValue = "Bad Initialization";
if(quality){
tempTime = errorTime;
tempTime.tm_sec = (errorTime.tm_sec+modifiedBy);
mktime( &tempTime);
std::string year, month, day, hour, minute, second;
// This compiler does not support the C++11 std::to_string but there is a workaround with stringstreams
// http://www.cplusplus.com/articles/D9j2Nwbp/
year = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime.tm_year+1900)) )->str();
month = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime.tm_mon+1)) )->str();
day = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime.tm_mday)) )->str();
hour = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime.tm_hour)) )->str();
minute = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime.tm_min)) )->str();
second = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime.tm_sec)) )->str();
if(month.length() == 1) { month = "0" + month; }
if(day.length() == 1) { day = "0" + day; }
if(hour.length() == 1) { hour = "0" + hour; }
if(minute.length() == 1) { minute = "0" + minute; }
if(second.length() == 1) { second = "0" + second; }
returnValue = year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;
}
return returnValue;
}
bool CTimestamp::good(){
return quality;
}
==原始问题在这条线上开始==
我需要一些自定义时间戳功能,我正在尝试为它创建一个类。不幸的是,当我尝试调用其中一个函数并且我不太清楚为什么会崩溃我的程序时,特别是考虑到当我在一个较小的玩具程序中使用它来测试类时它不会崩溃的事实。
#ifndef __TIMESTAMP_H
#define __TIMESTAMP_H
#include <string>
#include "time.h"
#include "debug.h"
class CTimestamp {
private:
std::string timestamp;
time_t rawtime;
struct tm * errorTime;
struct tm * tempTime;
bool quality;
public:
CTimestamp();
void set(std::string inputTime);
std::string get();
std::string get(int modifiedBy);
bool good();
void getWeekday(); // Mainly for testing purposes - if this returns
// the correct weekday for your modified timestamp,
// you probably modified it correctly.
};
#endif
我打电话时出现问题
std::cout << timeStamp.get(-30);
具体来说,此时:
year = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_year+1900)) )->str();
以下方法的一部分:
std::string CTimestamp::get(int modifiedBy){
if ( 1 < __DEBUG__ ){std::cout << "\nDEBUG " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;}
std::string returnValue = "Bad Initialization";
if(quality){
tempTime->tm_year = errorTime->tm_year;
tempTime->tm_mon = errorTime->tm_mon;
tempTime->tm_mday = errorTime->tm_mday;
tempTime->tm_hour = errorTime->tm_hour;
tempTime->tm_min = errorTime->tm_min;
tempTime->tm_sec = errorTime->tm_sec;
mktime(tempTime);
tempTime->tm_sec = tempTime->tm_sec + modifiedBy;
mktime(tempTime);
std::string year, month, day, hour, minute, second;
if ( 1 < __DEBUG__ ){std::cout << "\nDEBUG " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;}
// This compiler does not support the C++11 std::to_string but there is a workaround with stringstreams
// http://www.cplusplus.com/articles/D9j2Nwbp/
year = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_year+1900)) )->str();
month = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_mon+1)) )->str();
day = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_mday)) )->str();
hour = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_hour)) )->str();
minute = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_min)) )->str();
second = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_sec)) )->str();
if ( 1 < __DEBUG__ ){std::cout << "\nDEBUG " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;}
if(month.length() == 1)
{
month = "0" + month;
}
if(day.length() == 1)
{
day = "0" + day;
}
if(hour.length() == 1)
{
hour = "0" + hour;
}
if(minute.length() == 1)
{
minute = "0" + minute;
}
if(second.length() == 1)
{
second = "0" + second;
}
if ( 1 < __DEBUG__ ){std::cout << "\nDEBUG " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;}
returnValue = year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;
if ( 1 < __DEBUG__ ){std::cout << "\nDEBUG " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;}
}
if ( 1 < __DEBUG__ ){std::cout << "\nDEBUG " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;}
return returnValue;
}
修改
好的,这让我感到奇怪:
当我打电话
std::cout << timeStamp.get();
它在我指示的线路上崩溃了。
当我改为
时std::string hey = timeStamp.get();
std::cout << hey;
它在第二个__DEBUG__
语句(if(quality)
之后)
编辑编辑
errorTime在这里初始化:
void CTimestamp::set(std::string inputTime){
quality = 1;
int year, month, day, hour, minute, second;
if (19 == inputTime.length()){
inputTime.replace(10,1," ");
inputTime.replace(13,1,":");
inputTime.replace(16,1,":");
year = atoi(inputTime.substr(0,4).c_str());
month = atoi(inputTime.substr(5,2).c_str());
day = atoi(inputTime.substr(8,2).c_str());
hour = atoi(inputTime.substr(11,2).c_str());
minute = atoi(inputTime.substr(14,2).c_str());
second = atoi(inputTime.substr(17,2).c_str());
timestamp = inputTime;
}
else{
quality = 0;
}
if(quality){
// Get current time with the "time_t time(struct tm * timeptr)" function from time.h
time(&rawtime);
// Change to local time
errorTime = localtime(&rawtime);
// Change to the time of the timestamp
errorTime->tm_year = year - 1900; //Years since 1900
errorTime->tm_mon = month - 1; //Months since january
errorTime->tm_mday = day; //Day of the month
errorTime->tm_hour = hour; //Hours since midnight
errorTime->tm_min = minute; //minutes since hour
errorTime->tm_sec = second; //Seconds since minute
// modifies errorTime so overflows in lower units increment higher units then sets tm_wday and tm_yday
mktime ( errorTime );
}
}
编辑编辑
我试图摆脱花哨的指针工作,并允许它占用更多的线。不幸的是,它似乎不起作用:
/*
year = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_year+1900)) )->str();
month = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_mon+1)) )->str();
day = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_mday)) )->str();
hour = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_hour)) )->str();
minute = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_min)) )->str();
second = static_cast<std::ostringstream*>( &(std::ostringstream() << (tempTime->tm_sec)) )->str();
*/
int timeConvertINT;
std::ostringstream timeConvertOSS;
timeConvertINT = (tempTime->tm_year)+1900;
timeConvertOSS << timeConvertINT;
year = timeConvertOSS.str();
timeConvertINT = (tempTime->tm_mon)+1;
timeConvertOSS << timeConvertINT;
month = timeConvertOSS.str();
timeConvertINT = (tempTime->tm_mday);
timeConvertOSS << timeConvertINT;
day = timeConvertOSS.str();
timeConvertINT = (tempTime->tm_hour);
timeConvertOSS << timeConvertINT;
hour = timeConvertOSS.str();
timeConvertINT = (tempTime->tm_min);
timeConvertOSS << timeConvertINT;
minute = timeConvertOSS.str();
timeConvertINT = (tempTime->tm_sec);
timeConvertOSS << timeConvertINT;
second = timeConvertOSS.str();
编辑编辑编辑
咦。所以看起来ostreamstring不是这里的罪犯 - 即使我评论所有OSS功能并只是硬编码回复,它也会在那条线路上崩溃。
这意味着在这个区块中:
if(quality){
if ( 1 < __DEBUG__ ){std::cout << "\nDEBUG " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;}
tempTime->tm_year = errorTime->tm_year;
tempTime->tm_mon = errorTime->tm_mon;
tempTime->tm_mday = errorTime->tm_mday;
tempTime->tm_hour = errorTime->tm_hour;
tempTime->tm_min = errorTime->tm_min;
tempTime->tm_sec = errorTime->tm_sec;
mktime(tempTime);
if ( 1 < __DEBUG__ ){std::cout << "\nDEBUG " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;}
tempTime->tm_sec = tempTime->tm_sec + modifiedBy;
mktime(tempTime);
std::string year, month, day, hour, minute, second;
if ( 1 < __DEBUG__ ){std::cout << "\nDEBUG " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;}
year = "2013";
month = "11";
day = "05";
hour = "12";
minute = "00";
second = "00";
当我将其称为
时,我会看到第一个调试输出(以及之后没有)std::string hey = timeStamp.get();
std::cout << hey;
但是当我把它称为
时std::cout << timeStamp.get();
我在
之后看到了调试输出std::string year, month, day, hour, minute, second;
答案 0 :(得分:3)
神秘的崩溃和指针组合在一起,因此请在取消引用之前检查tempTime
和errorTime
是否指向有效对象。发布的代码不会显示您初始化tempTime
的位置,因此这就是从哪里开始查看。
除了为指针赋值外,还要确保在使用指针时对象的生命周期仍然有效。您不希望将指针保存到超出范围的临时对象。
答案 1 :(得分:2)
代码“似乎”合法,但正式 - 它实际上是不正确的,因为你正在拿一个临时的地址。 &(std::ostringstream() << (tempTime->tm_year+1900))
。
你可以轻松避免它 - 只需写(std::ostringstream() << (tempTime->tm_year+1900)).str()
即可。如果它仍然崩溃 - 尝试给std :: ostringstream()一个名称,比如
std::ostringstream() oss;
oss << (tempTime->tm_year+1900);
oss.str();
如果它也没有帮助 - 我暂时没有想法。