Newbie question: Saving Files? (C++)
Can anyone tell me, or point me in the direction of a tutoral, how to allow file saving so the player can continue playing where they left off after the program is shut down.
Edited by - afults on March 18, 2002 8:10:50 PM
How much land does a man need? "...sex feet from his head to his heels was all he needed."
well, as i know, as long as you know how to to open and write to a file and later on read it, you already know how to save your a game,
http://www.dualforcesolutions.comProfessional website designs and development, customized business systems, etc.,
You will need to use get,seek,put,tell etc. that are included in fstream.h
Sorry if this isn''t much help but I haven''t used them in a while myself. I''ll find some of my old code tonight and post it tomorrow.
Sorry if this isn''t much help but I haven''t used them in a while myself. I''ll find some of my old code tonight and post it tomorrow.
This question is more complex than it seems. Answering it in full is the work of a reasonably detailed article, but I''ll give you a quick primer.
Say you''ve written the game and you wish to save the game state. The first thing you need to do is decide on a format. For the smallest possible data file, the format will need to be relatively fixed, with the variable portions being declared in a header. For less demanding applications, numerous solutions exist. We''ll consider the less demanding solutions first.
Simple Text Files
Open/create a file and throw the values in, in some specified order. Read them back out in the same order. Dirty, quick, but you''re done and home before dinner''s cold.
To read, use ifstream instead of ofstream and >> instead of << (I''d also suggest renaming the variable to fin or something like that).
INI File-Style
Windows has a bunch of functions for dealing with initialization (.ini) files, a holdover (at least to Microsoft) from the 16-bit Windows days, before there was the registry. In those days, every application that wanted to maintain information between sessions wrote them to an .ini file, which was structured like so:
You were free to use any names for SectionName# and *VariableName#; I just named them so to illustrate the fact that they had to be unique within their section. You wrote values to .ini files using Write[Private]ProfileSection, Write[Private]ProfileString and Write[Private]ProfileStruct. Reading data was a question of using the Get* complements of these functions. The [] denotes optional; there are not "private" versions of these functions.
You can either use the Windows .ini functions (if you''re writing for Windows), or you can emulate them using C++. The cool thing about the .ini file functions is that they''re first cousins (more like siblings, actually) of Registry functions that are nearly identical in function, but have fairly different names.
Here''s some C++ code that works in similar fashion.
Ugh! Why was that so nasty?
C++ I/O doesn''t support insertion into files, so you have to read the data out into a buffer, modify it in the middle and then write it all back out. For the above procedure to work, the fstream must have been opened with ios::in|ios::out (read/write/no append).
Well, that''s probably overkill (and ugly, and inefficient). And it doesn''t buy you much. So what other options do I have?
Binary Savegame Files
Ok, this is where things get grimy (enter Noreaga beat...).
A full discussion of implementing a binary savegame format would, frankly, scare you, so I''ll simply discuss the theory.
First, you decide on a format. This is a conceptual layout of how the file will be structured, and might contain info to allow a single file represent several games by the same player, etc. You''ll need a file header which will contain information about the data in the file itself. Headers are usually at the top (head) of the file, and are always of fixed size. They may contain values that indicate the sizes of various other portions of the data.
Next, you''ll need a data layout - how the actual game data is stored. Depending on how large/complex your game is, this might be fairly involved. You might also want to consider using a chunk-based format, where individual chunks can easily be read from and written to disk.
Finally, you''ll need to actually write the code, and note that this must be done in binary mode. In this mode, Windows will not convert your newlines or any other special characters but will "dump" the binary equivalent of your data to file.
That''s it, in brief. Hopefully you can now make an informed decision - and maybe even implement your own simple savegame files. Good luck!
[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!
Say you''ve written the game and you wish to save the game state. The first thing you need to do is decide on a format. For the smallest possible data file, the format will need to be relatively fixed, with the variable portions being declared in a header. For less demanding applications, numerous solutions exist. We''ll consider the less demanding solutions first.
Simple Text Files
Open/create a file and throw the values in, in some specified order. Read them back out in the same order. Dirty, quick, but you''re done and home before dinner''s cold.
void WriteStateToFile(GameState & gs, std::string filename){ std::ofstream fout; fout.open( filename.c_str() ); if(fout.fail()) return; // in production code I would throw and exception... fout << gs.prop1 << ''\n'' << gs.prop2 << ''\n'' ... << gs.propN << endl; fout.close();}
To read, use ifstream instead of ofstream and >> instead of << (I''d also suggest renaming the variable to fin or something like that).
INI File-Style
Windows has a bunch of functions for dealing with initialization (.ini) files, a holdover (at least to Microsoft) from the 16-bit Windows days, before there was the registry. In those days, every application that wanted to maintain information between sessions wrote them to an .ini file, which was structured like so:
[SectionName1]S1VariableName1=S1Value1S1VariableName2=S1Value2...S1VariableNameN=S1ValueN[SectionName2]S2VariableName1=S2Value1S2VariableName2=S2Value2...S2VariableNameN=S2ValueN...
You were free to use any names for SectionName# and *VariableName#; I just named them so to illustrate the fact that they had to be unique within their section. You wrote values to .ini files using Write[Private]ProfileSection, Write[Private]ProfileString and Write[Private]ProfileStruct. Reading data was a question of using the Get* complements of these functions. The [] denotes optional; there are not "private" versions of these functions.
You can either use the Windows .ini functions (if you''re writing for Windows), or you can emulate them using C++. The cool thing about the .ini file functions is that they''re first cousins (more like siblings, actually) of Registry functions that are nearly identical in function, but have fairly different names.
Here''s some C++ code that works in similar fashion.
#include <ifstream>#include <iostream>#include <string>using std::endl;using std::fstream;using std::string;void WriteDataValue(fstream fout, string section, string key, string value){ size_t pos = 0; string str, scmp = "[" + section + "]"; string buf;// // find the section fout.clear(); // clear failbits, if any fout.seek(ios::beg); while(!fout.eof()) { getline(fout, str); if(str == scmp) // found the section break; buf += (str + "\n"); // append data to buffer }// // find the key while(!fout.eof()) { fout >> str; if( str == key ) break; }// // okay, we''ve found the position to insert our value buf += ("=" + value + "\n");// // now get the rest of the file while(!fout.eof()) { getline(fout, str); buf += (str + "\n"); }// // now write the whole thing back to the file in one fell swoop fout << buf;}
Ugh! Why was that so nasty?
C++ I/O doesn''t support insertion into files, so you have to read the data out into a buffer, modify it in the middle and then write it all back out. For the above procedure to work, the fstream must have been opened with ios::in|ios::out (read/write/no append).
Well, that''s probably overkill (and ugly, and inefficient). And it doesn''t buy you much. So what other options do I have?
Binary Savegame Files
Ok, this is where things get grimy (enter Noreaga beat...).
A full discussion of implementing a binary savegame format would, frankly, scare you, so I''ll simply discuss the theory.
First, you decide on a format. This is a conceptual layout of how the file will be structured, and might contain info to allow a single file represent several games by the same player, etc. You''ll need a file header which will contain information about the data in the file itself. Headers are usually at the top (head) of the file, and are always of fixed size. They may contain values that indicate the sizes of various other portions of the data.
Next, you''ll need a data layout - how the actual game data is stored. Depending on how large/complex your game is, this might be fairly involved. You might also want to consider using a chunk-based format, where individual chunks can easily be read from and written to disk.
Finally, you''ll need to actually write the code, and note that this must be done in binary mode. In this mode, Windows will not convert your newlines or any other special characters but will "dump" the binary equivalent of your data to file.
That''s it, in brief. Hopefully you can now make an informed decision - and maybe even implement your own simple savegame files. Good luck!
[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!
how do you get into binary mode, I thought you could not do stright binary in C++ but instead had to go through hex...
[email=esheppard@gmail.com]esheppard@gmail.com[/email]
quote: Original post by elis-cool
how do you get into binary mode, I thought you could not do stright binary in C++ but instead had to go through hex...
Use mode ios_base::binary.
This also pointed out to me that I used the old mode bit. To be Standard Compliant, your code should use ios_base::in and ios_base::out, not ios::in and ios::out.
[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!
Try reading my filemapping tutorial. It will help you with the file access functions specific of Windows.
What you''ll need to write in the files, are the data you''d need to make the game start from the same place where it was saved, the next time you load it.
--DK
--H. Hernán Moraldo
http://www.hhm.com.ar/
Sign up to the HHM''s developers'' newsletter.
What you''ll need to write in the files, are the data you''d need to make the game start from the same place where it was saved, the next time you load it.
--DK
--H. Hernán Moraldo
http://www.hhm.com.ar/
Sign up to the HHM''s developers'' newsletter.
--DK--H. Hernán Moraldohttp://www.hhm.com.ar/Sign up to the HHM's developers' newsletter.
WOW! Thanks I think I finally get it, now all those weeks I spent trying to understand this finally has produced some results. I think I can figure the rest out on my own. THANK YOU so very much!
How much land does a man need? "...sex feet from his head to his heels was all he needed."
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement