Сбой при использовании & quot; time.h & quot;

== ФИНАЛЬНЫЙ КЛАСС ПРОДОЛЖАЕТ ЭТУ ЛИНИЮ ==

Это не было проблемой с 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;

2

Решение

Таинственные сбои и указатели идут вместе, поэтому проверьте, что tempTime а также errorTime указать на действительные объекты, прежде чем разыменовывать их. Размещенный код не показывает, где вы инициализируете tempTime так что вот где начать искать.

В дополнение к назначению значений указателям, убедитесь, что время жизни объекта также остается действительным при использовании указателей. Вы не хотите сохранять указатель на временный объект, который вышел из области видимости.

3

Другие решения

Код «кажется» законным, но формально — на самом деле он плохо сформирован, потому что вы берете временный адрес. &(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();

Если и это не поможет — у меня пока нет идей.

2

По вопросам рекламы [email protected]