Thread: Help with some data writing - I can't make it more speciefic then that

  1. #1
    Registered User
    Join Date
    Aug 2010
    Posts
    13

    Help with some data writing - I can't make it more speciefic then that

    Ok, How are you guys doing? the reason why i'm posting is because i seem to run into some "techincal difficuties" when writing data from a buffer, mainly this:


    Player Name: Gordon
    Player Health: 100
    Player Shields: 100
    Player Position:
    X: 300
    Y: 100
    Z: 100
    now it looks good but the buffer is 256 and when i save the file and open it, there's data written to file that's a bunch of "i"s so i'm wondering how can you make a char buffer that will know exactly how much the size has to be for the data ro be written to file and not have that left over garbage? maybe i'm not explainging my self good.......:-p anyways, if u don't get it i'll just post the file or the picture on photobucket.

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    There's a C way to address the problem and a C++ way. The C++ way is to use string streams (because you mentioned buffering. Files do their own buffering too, but never the less:
    Code:
     
    #include <sstream>
    #include <fstream>
    
    istringstream buffer;
    
    buffer << "Player Name: Gordon\n";
    buffer << "Player Health: 100\n";
    buffer << "Player Shields: 100\n";
    buffer << "Player Position:\n"
    buffer << "X: 300\n";
    buffer << "Y: 100\n";
    
    ofstream savefile;
    savefile.open ("slot001.sav" );
    if (savefile.is_open ()) {
       savefile << buffer.str ();
       savefile.close ();
    }
    It really is as simple as that. stringstreams take everything into a string buffer that you can copy and insert to a file so it doesn't matter if your code looks like this. The idea is more important. And again, files do their own buffering, so you may be creating a need for stringstreams where there isn't one.

    The C way is not as pretty but it works:
    Code:
    #include <cstdio>
    #include <cstdlib>
    
    char *buffer = 0;
    int buffersize = 0;
    FILE *savefile = 0;
    
    savefile = fopen ("NUL", "w");
    if (savefile != 0) {
       buffersize = fprintf(savefile, 
          "Player name: %s\nPlayer health: %d\nPlayer sheilds:%s\nPlayer position:\nX:%d\nY:%d\n"
           , /* variables */ );
       buffer = (char*) malloc (buffersize + 1);
       fclose (savefile);
    }
    
    savefile = fopen ("slot001.sav" , "w");
    if (savefile != 0) {   
       if (buffer != 0) {
          sprintf (buffer, ...);
          fprintf (savefile, "%s", buffer);
          fclose (savefile);
       }
    }
    The C method should not be too unfamiliar if you have ever written files before. fprintf always returns the number of characters it prints, so it can be a handy way to determine the length of some almost random string. So you call it once for that, and call it again to actually write the file at some point.

    This method is nasty because it is platform dependent in its execution. NUL is a handy temp file that points nowhere in Windows. Other operating systems might have /dev/null or something different. You can mitigate this problem with some preprocessor magic (make the compiler identify the platform its on an compile a specific section of code).

    Not to mention the C method has the same caveat: C file I/O also uses buffers.

    But this is C++! A more managed way is possible, so I would use the first suggestion.

    Oh, btw, I did not compile these.
    Last edited by whiteflags; 08-07-2010 at 01:53 AM. Reason: freezer head

  3. #3
    Registered User
    Join Date
    Aug 2010
    Posts
    13
    One thing i should mention that those are part of a struct, i didn't write them directly buit they are variables, but i'll try the C++ way, thanks

  4. #4
    Registered User
    Join Date
    Aug 2010
    Posts
    13
    Code:
    
    struct Data
    {
    	string PlayerName;
    	unsigned int Health;
    	unsigned int Shields;
    	
    	float Xpos;
    	float Ypos;
    	float Zpos;
    };
    
    bool SaveData(Data &data);
    
    bool LoadData(Data &data);
    
    Data player;
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	player.PlayerName = "Gordon";
    	player.Health    = 100;
    	player.Shields   = 100;
    	player.Xpos		 = 300;
    	player.Ypos		 = 100;
    	player.Zpos		 = 100;
    
    	if(SaveData(player))
    	{
    		cout << "Data Saved" << endl;
    	}
    
    	cout << "Would u like to load it back? " << endl;
    	char in;
    	cin >> in;
    	if(in =='y')
    	{
    		LoadData(player);
    	}
    
    	cout << "Size of: " << sizeof(Data) << endl;
    	while(1)
    	{}
    	return 0;
    }
    
    bool SaveData(Data &data)
    {
    	char DataBuffer[256];
    
    	std::ofstream DataFile("Player.data");
    
    	DataFile.setf( ios_base::binary );
    	if(DataFile.is_open())
    	{
    		sprintf(DataBuffer,"Player Name: %s\n"
    			"Player Health: %d\n"
    			"Player Shields: %d\n"
    			"Player Position: \n"
    			"X: %.f\n"
    			"Y: %.f\n"
    			"Z: %.f\n",data.PlayerName.c_str(),data.Health,data.Shields,
    			data.Xpos,data.Ypos,data.Zpos);
    
    		DataFile.write((char*)&DataBuffer,sizeof(DataBuffer));
    
    		if(DataFile.is_open())
    		{
    			DataFile.close();
    		}
    	}
    
    	return true;
    }
    
    bool LoadData(Data &data)
    {
    	char BufferData[256];
    
    	ifstream PlayerData("Player.data");
    
    	sprintf(BufferData,"Player Name: %s\n"
    			"Player Health: %d\n"
    			"Player Shields: %d\n"
    			"Player Position: \n"
    			"X: %.f\n"
    			"Y: %.f\n"
    			"Z: %.f\n",data.PlayerName.c_str(), data.Health,data.Shields,data.Xpos,
    			data.Ypos,
    			data.Zpos);
    
    	if(PlayerData.is_open())
    	{
    		PlayerData.read((char*)BufferData,sizeof(BufferData));
    
    		if(PlayerData.is_open())
    		{
    			PlayerData.close();
    		}
    	}
    
    	cout << "Player Name: " << data.PlayerName << endl;
    	cout << "Player Health: " << data.Health << endl;
    	cout << "Player Shileds: " << data.Shields << endl;
    	cout << "Player Position: " << endl;
    	cout << "X: " << data.Xpos << endl;
    	cout << "Y: " << data.Ypos << endl;
    	cout << "Z: " << data.Zpos << endl;
    
    	return true;
    }
    As you can see i used the write/read functions of the streams to write files now that seems to be better then using << but i could be wrong, are there any advantages to using write/read? or should i avoid them like the plague?

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    There is one reason not to use write() and read() right now. One reason is because you're using text files, and because you're using a text file, you can treat ifstreams like cin, and ofstreams like cout, instead. If write() is better than operator<< I wouldn't know why: if it's better because you care about performance, you're just guessing. File I/O is a bottleneck anyway. That is why files do their own buffering: to reduce the number of reads and writes performed. For the future, the write() and read() functions are quite useful if you're trying to use a binary file, though.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help in C programming (too lazy)
    By cwillygs in forum C Programming
    Replies: 12
    Last Post: 04-20-2010, 12:23 AM
  2. Read data of a page frame (linux) make freeze the system
    By hahai in forum Linux Programming
    Replies: 1
    Last Post: 09-16-2009, 09:01 AM
  3. data structure design for data aggregation
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 05-20-2008, 06:43 AM
  4. Writing data to a Printer Device Context
    By leojose in forum Windows Programming
    Replies: 2
    Last Post: 05-12-2005, 10:08 PM
  5. Program Crashing
    By Pressure in forum C Programming
    Replies: 3
    Last Post: 04-18-2005, 10:28 PM