== ФИНАЛЬНЫЙ КЛАСС ПРОДОЛЖАЕТ ЭТУ ЛИНИЮ ==
Это не было проблемой с 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;
Таинственные сбои и указатели идут вместе, поэтому проверьте, что tempTime
а также errorTime
указать на действительные объекты, прежде чем разыменовывать их. Размещенный код не показывает, где вы инициализируете tempTime
так что вот где начать искать.
В дополнение к назначению значений указателям, убедитесь, что время жизни объекта также остается действительным при использовании указателей. Вы не хотите сохранять указатель на временный объект, который вышел из области видимости.
Код «кажется» законным, но формально — на самом деле он плохо сформирован, потому что вы берете временный адрес. &(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();
Если и это не поможет — у меня пока нет идей.