PDA

View Full Version : std::fstream Is not writing :(


Lazy
26-02-2005, 00:39
This is making me go insane, for some reason nothing is being written when I call std::fstream::write or std::fstream::put.
It's gotta be something simple but I'm just not seeing it, thanks in advance for any help :D.


// Opens the crash check file, returns true if success
bool CCrashFile_HL1::Open( void ) {
char szPath[ 256 ]; // Path to crashstatus.bin

// Get the game directory
GET_GAME_DIR( szPath );

// Append the crashstatus.bin path and fix the path for win32
strncat( szPath, "/crashstatus.bin", sizeof( szPath ) );
CMapcycle_HL1::FixpathWin32( szPath ); // Note: Now I remember why I made this static method public....

// Try and open crashstatus.bin in read only mode to see if it exists
m_fCrashstatus = new std::fstream( szPath, std::ios.in | std::ios.binary );

// If allocation failed, exit now
if ( ! m_fCrashstatus )
return false;

// If the file wasn't opened try and create a new one.
// OR, if the file has no content.
if ( ! m_fCrashstatus->is_open( ) || m_fCrashstatus->eof( ) ) {
// If we're just eof, close the file now...
if ( m_fCrashstatus->is_open( ) )
m_fCrashstatus->close( );

// Re-open the file for writing
m_fCrashstatus->open( szPath, std::ios.out | std::ios.binary );

// If it didn't open just get off here
if ( ! m_fCrashstatus->is_open( ) ) {
delete m_fCrashstatus; // Clean up used memory
return false;
}

// Write a 1 into the stream so we assume the server
// exited cleanly last time.
m_fCrashstatus->write( "Test!\n", 7 );

// Close the file now
m_fCrashstatus->close( );
}

// If the file was opened earlier, we have to close it now
// to re-open it in write mode.
if ( m_fCrashstatus->is_open( ) )
m_fCrashstatus->close( );

// Success!
return true;
}

Pierre-Marie Baty
26-02-2005, 03:44
What happens? Crash? lockup? Or just nothing... and nothing in the file?

Lazy
26-02-2005, 03:51
The file has 0 bytes in it, that makes absolutely no sense at all.
I did a couple of lines with ofstream and the << operator and that worked but unfortunately not in binary mode.
I got rid of all that C++ file i/o crap out of frustration and went back to the C style fopen way of doing it, doesn't seem to like reading bools though.
I still wish I knew why it didn't write, all my other code is using C++ file i/o and works perfectly ( though maybe thats because its only reading ).

koraX
26-02-2005, 10:47
omg, messy code.

Why do you have pointers to fstream ?
Tell me what precisely this function should do and I'll fix it.


after new, check !m_fCrashstatus is totally useless. If allocation fails, exception will be thrown.

eof doesn't return true if file size is 0.

use std::fstream::binary instead of std::ios.binary, same for other types.

write ("Test!\n", 6), not write("Test!\n", 7). you cannot assume that \n is 2 characters. If you want to write \n, use text mode.

Lazy
26-02-2005, 11:10
1. Yeah, its only that function though all the others are much cleaner.
2. It wasn't always like that, I changed it a while ago just for the hell of it to see if it would work ( bored at the time, and it was late )
3. Hmm, thats new... Thanks for that info.
4. Again, never knew that or have forgotten it since I hadn't used C++ i/o in a long time.
5. Ok
6. That was leftover, I do know that \n is one character I was just accounting for the extra \0 that the compiler adds onto strings.

The code I posted is a total hack I admit, I don't really smooth things out until I know its going to work.

The plugin in general is supposed to detect if the server has crashed and change the map on the next restart.
All it does is checks the content of a file at startup, if its 1 then the server exited cleanly.
If it's 0 that means ServerDeactivate wasn't called and the server must have crashed so it chooses a random map from mapcycle.txt.

koraX
26-02-2005, 12:18
Ok so here is some simple function
- server crashed if : file does not exists, file empty or first character in file is not '1' (0x31)
- server clean if : file exists and first character in this file is '1' (0x31)

bool Crashed () {
// acquire file name
char tempBuffer [1024];
GET_GAME_DIR (tempBuffer);
std::string fileName = tempBuffer;
// fix path, unix syntax
replace (fileName.begin(), fileName.end(), '\\', '/');
// our file
fileName += "/crashstatus.bin";

// open file
std::ifstream file (fileName.c_str());
if (!file.is_open()) // file does not exists, server crashed
return true;

char contents = 0; // important, we must initialize here
file >> contents; // if file is empty, contents will be unchanged
file.close();

if (contents != '1')
return true;
return false; // not crashed
}

Lazy
26-02-2005, 13:47
Thanks!
That makes alot more sense now.

mirv
27-03-2005, 08:35
Don't forget to flush the buffer contents - it may not be writing to the actual file because it's waiting for a more efficient time to swap it out of memory to the disk. fflush for some of the C file i/o, or just file.flush() for C++ I think.

@$3.1415rin
27-03-2005, 13:44
when the file is closed, the buffers are flushed anyway, so don't waste too much buffering advantages by using flush everywhere :)