ofstream issues

Started by
8 comments, last by GameDev.net 18 years, 11 months ago
Hi, I am creating a logger class but I am having a run-time error. Basically I use this code to open the log:

int CLogger::openLog(const char* filename)
{
	std::ofstream logFile(filename);
	if (!logFile.is_open())
	{
		return -1; //Error! Couldn't open the log
	}
	writeLog("--LOG STARTED--");
	return 0;
}
Then, I use this code to write to the log (the overloaded method other classes throughout the code use):

int CLogger::writeLog(char* text)
{
	logFile << text << "\n";
	logFile.flush(); 
	return 1;
}

int CLogger::writeLog(int text)
{
	logFile << text << "\n";
	logFile.flush(); 
	return 1;
}

int CLogger::writeLog(std::string text)
{
	const char* charText = text.c_str();
	logFile << charText << "\n";
	logFile.flush(); 
	return 1;
}
The error though, is strange. The log outputs --LOG STARTED-- as it should in the openLog method, but then when I call upon it from an outside class such as this one:

int CGameState_Menu::preRun()
{
	log->writeLog("preRun() menu state");
	return 1;
}
I get a run-time error. Here is the call-stack:

>	msvcp71d.dll!std::operator<<<std::char_traits<char> >(std::basic_ostream<char,std::char_traits<char> > & _Ostr={...}, const char * _Val=0x00455f48)  Line 711 + 0x3	C++
 	OninWars_d.exe!CLogger::writeLog(char * text=0x00455f48)  Line 32 + 0x17	C++
 	OninWars_d.exe!CGameState_Menu::preRun()  Line 22	C++
 	OninWars_d.exe!CGameManager::run()  Line 106 + 0x24	C++
 	OninWars_d.exe!main()  Line 17	C++
So, it dies on this line:

	streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count
		? 0 : _Ostr.width() - _Count;
in ostream. Any ideas why this could be?
-Brcolow-
Advertisement
I'd guess it's the fact that you create the log as a local variable in the open function, then call it from other functions. Although really I'm not sure how you got that to compile at all.
You know, I thought about that and saw it but there is no way in my limited knowledge to make it global. You see, there is no = operator for ofstream, so I can't do something like:

std::ofstream log (filename);
this->logFile = log;

So I'm not sure what to do..
-Brcolow-
if you have logFile declared as a member variable, then you should remove the local variable in openLog, but put in
logFile.open(filename);
I tried that before..but just to make sure I tried it again, and the exact same error occured. Strange...I know :(
-Brcolow-
For now I will spare you various lectures about coding style...

Quote:Original post by brcolow
You know, I thought about that and saw it but there is no way in my limited knowledge to make it global. You see, there is no = operator for ofstream, so I can't do something like:

std::ofstream log (filename);
this->logFile = log;

So I'm not sure what to do..


Initialize it in the class constructor (via an initializer list), rather than trying to assign it later:

// where logFile is a member of CLoggerCLogger::CLogger() : logFile(filename) {  if (!logFile.is_open()) {    // throw an exception  }  writeLog("--LOG STARTED--");}CLogger::~CLogger() {  writeLog("--LOG FINISHED--");  logFile.close(); // probably not needed...}


Of course, default-constructing one instead and later calling its .open() should work too, but this is a cleaner approach, really.
I see, thanks for the help but I am a little unclear about what you said.

What am I supposed to do for the class declaration of CLogger?

Also, I assume I should make filename a public member var..yes?

Also, do I need to do anything special when creating the class now?
-Brcolow-
I think I answered my own questions, basically I made the class declaration like so:

class CLogger : std::ofstream

The code compiles fine now, but the problem is that I am getting a run-time error. Here's the call-stack:

Quote:
> msvcr71d.dll!_fsopen(const char * file=0xcdcdcdcd, const char * mode=0x104ea5c4, int shflag=64) Line 55 + 0x3 C
msvcr71d.dll!fopen(const char * file=0xcdcdcdcd, const char * mode=0x104ea5c4) Line 116 + 0xf C
msvcp71d.dll!std::_Fiopen(const char * filename=0xcdcdcdcd, int mode=2, int __formal=438) Line 56 + 0x15 C++
msvcp71d.dll!std::basic_filebuf<char,std::char_traits<char> >::open(const char * _Filename=0xcdcdcdcd, int _Mode=2, int _Prot=438) Line 167 + 0x1a C++
msvcp71d.dll!std::basic_ofstream<char,std::char_traits<char> >::basic_ofstream<char,std::char_traits<char> >(const char * _Filename=0xcdcdcdcd, int _Mode=2, int _Prot=438) Line 628 + 0x1a C++
OninWars_d.exe!CLogger::CLogger() Line 8 + 0xcd C++
OninWars_d.exe!CGameManager::CGameManager() Line 10 + 0x2d C++
OninWars_d.exe!main() Line 15 + 0x2e C++
OninWars_d.exe!mainCRTStartup() Line 398 + 0x11 C


That line is:

        _ASSERTE(*file != _T('\0'));


in fopen.c

Any ideas? :(
-Brcolow-
class Logger {public:  Logger(std::string filename) : logFile(filename.c_str()) {    if(!logFile.is_open())      throw std::runtime_error(std::string("Unable to open log file: ") + filename);  }  ~Logger() {  }  void WriteEntry(std::string entry) {    logFile<<entry<<std::endl;  }private:  std::ofstream logFile;};

extend as needed.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Thanks for all of your help guys...I finally got it sorted out. +ratings for all :D

This topic is closed to new replies.

Advertisement