Archived

This topic is now archived and is closed to further replies.

graveyard filla

need help with reading from a file...

Recommended Posts

high, im working on a map editor for my pacman clone. anyway, i have finished most of the map editor. the only problem is ive never worked with reading/writing to a file before. i read some tutorials at gametutorials.com and figured out how to write to a file real easy. its the reading in of the file im having problems with. this is obviously a tile based game/map maker, my map array is [19][25] (y)(x). anyway, this is what my Save() function looks like:

void Save()
{
	ofstream fout;										

       fout.open("map.txt");				
																						
       for(int y = 0; y < 19; y++)
	{
		for(int x = 0; x < 25; x++)
		{
			fout << map[y][x];
		}

		fout<<endl;
	}

	fout.close();
}
now here is what a typical map.txt looks like if i save from inside my map editor:
   
1111111111100011111111111
1715888888881700017888888881517
17811811118170001781111811817
17811811118171111781111811817
178884848884882488848488817
17811817811181118111817811817
178888174888481784888417888817
171118171111181781111117811117
00017817888884848888817817000
111181781111111111181781111
888848881717071330171788848888
1111817178171701200017178171781111
00017817178171711111171781717817000
11118171788868886888171781111
178888171718178171717817811717888817
17811868881781717178178888811817
178111811118171717811118111817
17158885888858885888858881517
1111111111111111111111111
now, does anyone have any ideas on how i could read this file back into my map[][] array? im really knew to file input/output so any help is greatly appreciated. this is what i tried but its not working.
  
void Open()
{

	
	ifstream file_in("map.txt");

	if(!file_in)
		return;

	int x = 0;
	int y = 0;


	char temp; 

	while(y != 19) // Keep going until we reach the end of the map

	{
		file_in >> temp;

		map[y][x] = temp;
				

        // Increment 'x' every time we write a character until 'x' equals the 

		// width of map, then start 'x' back at zero

		if(++x == 25)
		{
			x = 0;
			y++; // We need to increment y so we effectively go down to the next line

				
		}

	} // end of 



   file_in.close();
		
	

}//end of open()


thanks for any help!! [edited by - graveyard filla on March 23, 2004 3:26:47 AM]

Share this post


Link to post
Share on other sites
also, i think that my open() function isnt working because some of the enums that represent tiles are 2 digits (see numbers like 17, 12, 11, ETC.) and some are 1 digit (1,2,0,4, ETC)

i think this is why its not working, although i dont really know what im doing so the whole function could be total crap. thanks again for any help

Share this post


Link to post
Share on other sites
Mkk    126
I had pretty much the same problem.. The problem is that when you are reading from file with >> operator, it reads so long that it finds a free space, so right now it will read a whole file in a first place.

change this line in Save() function:

fout << map[y][x];

to:

fout << map[y][x] << ' ';


and it should work..

btw. Those if/while loops in your open function looks pretty creepy, I would consider of changing them to for loops.. :-O

[edited by - Mkk on March 23, 2004 4:01:06 AM]

Share this post


Link to post
Share on other sites
hey,

actually, that didnt work. well, i figured i was causing problems by outputting my map the way i did (with being able to see the map as a 25x19 array in the map.txt file. anyway, i changed the format to this:


void Save()
{
ofstream fout; // Here we create an ofstream and we will call it "fout", like "cout".


fout.open("map.txt"); // We call a function from our ofstream object called open().

// We just tell open() the file name we want to open or create.

// If the file doesn't exist, it will create it for us once we start writing to it.

for(int y = 0; y < 19; y++)
{
for(int x = 0; x < 25; x++)
{
fout << map[y][x];
}

}

// close() closes the file for us. (very important)

fout.close();
}


anyway, if you dont understand what im saying, this output .txt file now looks like this:

  
00000000002222222222222222222222222222220000000000000000000000003333333333333333333333333333333333333333333309000000000000000033333333


anyway, this didnt work either. then i tried adding in the little space like you said, and that worked.

but id still like to know why my original way wasnt working. id like my map txt files to be somewhat readable if its possible

[edited by - graveyard filla on March 23, 2004 3:59:32 AM]

Share this post


Link to post
Share on other sites
Indeterminatus    129
By "readable" you mean, readable by a user who opens the file with a text-editor?

Anyways, I''d highly recommend a binary file format, because problems like digits per entry (as mentioned in a posting above) won''t occur. Furthermore, binary file format saves space on the harddisk.

You will need a kind of map editor anyways, because THAT''s what makes the map really "readable"



Indeterminatus

--si tacuisses, philosophus mansisses--

Share this post


Link to post
Share on other sites
Toolmaker    967
You better look into binary files. They make it alot easier and you can also add in a file header so you can maintain file versions. For example:

struct PACMANFILEHEADER
{
DWORD dwType;
DWORD dwVersion;
WORD wWidth;
WORD wHeight;
};


The header explained:
dwType
Type of file. You could make the value something you can recognize. For example: 0xAE

dwVersion
Version of the file. For now, just use MAKELONG(1, 0). To compare after you are done with loading, do:
if (Header.dwVersion != MAKELONG(1, 0)) // Error!

After you added new features to your game and updated the map editor, you can write the new loading code. In essence, you can even make the maps backwards compatible with loading. If you do this, you could release a new EXE and still be able to load older maps without all the new nifty features.

wWidth
The width of the map. If you implement variable map sizes in your game you actually have a pretty neat feacture

wHeight
The height of the map. Same as wWidth, having variabele map sizes is just cool. Don't forget to fix smooth scrolling

Ok, now we have that, we can do this:

// Psuedo code
ifstream File;
File.open("Map1.pac", ios::binary);
File.read((char *)&Header, sizeof(PACMANFILEHEADER));


After you read the header, do your checks, allocate the map data and the data at once:

File.read((char*)Map, sizeof(TileSize * (FileHeader.wWidth * FileHeader.wHeight));

This will load the map into memory and viola, you have you map easily loaded.

Saving is the same, but viceversa:
- Open output file
- Create fileheader
- Write header
- Write map data
- Close file

Toolmaker



-Earth is 98% full. Please delete anybody you can.

[edited by - toolmaker on March 23, 2004 4:18:00 AM]

Share this post


Link to post
Share on other sites
Indeterminatus    129
Forget the above post. I should read more carefully before replying :/.

The first version didn''t work because the stream "tokenizes" the string it reads, meaning that single entries are delimited with either spaces or newlines.
If you skip those spaces, on LINE would be read by the stream at once, leading to an I/O error (since you''ll try to read over the end of the file).



Indeterminatus

--si tacuisses, philosophus mansisses--

Share this post


Link to post
Share on other sites
Toolmaker    967
quote:
Original post by Indeterminatus
Forget the above post. I should read more carefully before replying :/.



I sure hope you don''t mean my post It''s pretty constructive and the way things are being handled by others too.

Toolmaker





-Earth is 98% full. Please delete anybody you can.

Share this post


Link to post
Share on other sites
Mkk    126
It wasn´t working at first place because this line:


file_in >> temp;


It will read the file so long until it hits the free space in the file so if you don´t have any free spaces in the file, it will read the whole file in to the variable at the first place (rather than reading just one number).

That´s why the spaces.. so >> operator understands to stop reading after the number.

If you want to those line changes, atleast I just putted
"\n" always after row and it didn´t make any problems.

Here´s my loops for reading writing:

Reading:


for (int x = 0; x < BOARD_WIDTH; x++)
{
for (int y = 0; y < BOARD_HEIGHT; y++)
{
in >> gameBoard[x][y];
}
}


Writing:


for (int x = 0; x < BOARD_WIDTH; x++)
{
for (int y = 0; y < BOARD_HEIGHT; y++)
{
out << gameBoard[x][y] << ' ';
}
out << "\n";
}



[edited by - Mkk on March 23, 2004 4:24:08 AM]

Share this post


Link to post
Share on other sites
Indeterminatus    129
quote:

I sure hope you don''t mean my post It''s pretty constructive and the way things are being handled by others too.



Sorry, Toolmaker . Of course I was referencing MY previous post, that would be the one before yours .

Should have made it absolute, not relative ...



Indeterminatus

--si tacuisses, philosophus mansisses--

Share this post


Link to post
Share on other sites
mkk.... thats pretty much exactly what my open() and save() functions look like... this makes for one long txt file... but i guess that doenst matter seeing as im using a map-editor anyway

whats the difference beteen binary and "regular" file reading/writing? whats so great about it and how do i use it? thanks for any help

Share this post


Link to post
Share on other sites