Sign in to follow this  

help reading in text file

This topic is 4840 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there, ive come accross a rather annoying problem with the map loading process of my game. It seems as though when trying to load in some data from a text file that contains the layout of a particular grid, it grabs not only the data but also a bunch of garbled characters that are faulting the loop and causing a access violation, at least thats what i think. Heres the text file
1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,3
1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1
1,1,1,1,1,1,1,1,4,1,1,1,3,3,3,3,1

and the code
void Grid::LoadMap(char * MapFile)
{
        char buffer[255];
	int k = 0; //line
	int j = 0; // for characters
	
	std::ifstream MAP(MapFile);
	//std::ofstream DEB("log.txt");

	if (MAP.is_open)
	{
		while (!MAP.eof())
		{
			MAP.getline (buffer,34,'\n');
			//DEB.write(buffer,34);

			if (buffer[0] != '#')
			{
				k++; //line
				j = 0; // clear
				for (unsigned int i=0;i<sizeof(buffer)/sizeof(char);i++)
				{
					if (buffer[i] != ',')
					{
						TileSrc[j][k] = (int)buffer[i];
						j++;
					}
				}
			}
		}
	}
	else
	{
		//do nothing for now
	}

	MAP.close(); //close map file
	//DEB.close();

}


evolutional - Please use source tags when posting code. See the FAQ for more information. [Edited by - evolutional on September 12, 2004 2:46:45 PM]

Share this post


Link to post
Share on other sites
Why has "buffer" a length of 255, if the lines you're reading have a length of 32? And your for-loop checks all 255 of them.

Share this post


Link to post
Share on other sites
for readibility:


void Grid::LoadMap(char * MapFile)
{
char buffer[255];
int k = 0; //line
int j = 0; // for characters

std::ifstream MAP(MapFile);
//std::ofstream DEB("log.txt");

if (MAP.is_open)
{
while (!MAP.eof())
{
MAP.getline (buffer,34,'\n');
//DEB.write(buffer,34);

if (buffer[0] != '#')
{
k++; //line
j = 0; // clear
for (unsigned int i=0;i<sizeof(buffer)/sizeof(char);i++)
{
if (buffer[i] != ',')
{
TileSrc[j][k] = (int)buffer[i];
j++;
}
}
}
}
}
else
{
//do nothing for now
}

MAP.close(); //close map file
//DEB.close();

}

Share this post


Link to post
Share on other sites
Quote:
Original post by WanMaster
Why has "buffer" a length of 255, if the lines you're reading have a length of 32? And your for-loop checks all 255 of them.


Yeah, i caught that too. But changing it didnt seem to make a difference.

heres a dump of the buffer

⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣#⌀
⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣#⌀
⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣#⌀
⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣#⌀
⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣#⌀
⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣#⌀
⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣⌣#⌀

etc etc etc

Share this post


Link to post
Share on other sites
lol well i think i may have fixed it, but now i get a message on compilation that the stack around 'buffer' was corrupted. Whatever .NET....whatever you say...

Share this post


Link to post
Share on other sites


void Grid::LoadMap(char *MapFile)
{
char buffer[1024] = "\0"; // file buffer
unsigned int ctr = 0; // counter
unsigned int y = 0, x = 0; // grid positions

//place and fix these acordingly within your class.
const int MAP_X = 17; // Number of elements horz in your map
const int MAP_Y = 17; // Number of elements vert in your map
char TileSrc[MAP_Y][MAP_X]; // your map data array

// open the map
std::ifstream MAP(MapFile);

// My map had better be open :)
if (MAP.is_open())
{
// clear buffers of garbage
memset(TileSrc, 0, sizeof(TileSrc));
memset(buffer, 0, sizeof(buffer));

// until end of file
while (!MAP.eof())
{
// read up to 1024 characters per line up to newline
MAP.getline(buffer, 1024);

// reset grid position x
x = 0;

// ignore comment lines?
if (buffer[0] != '#')
{
// process each file line
for (ctr = 0; ctr < strlen(buffer); ++ctr)
{
// only save if its a number
if (isdigit(buffer[ctr]))
{
TileSrc[y][x] = buffer[ctr];
x++;

}//if

}//for

// next line
y++;

}//if

}//while

// close the map file
MAP.close();

// display the map info (for debugging purposes)
/*cout << "Map is " << y << "x" << x << endl;

for (y = 0; y < MAP_Y; ++y)
{
for (x = 0; x < MAP_X; ++x)
{
cout << TileSrc[y][x] << " " << flush;

}//for

cout << endl;

}//for*/


}//if
else
{
//cerr << "Could not open map" << endl;

}//else

return;

}//Grid::LoadMap


Share this post


Link to post
Share on other sites
You're using std::ifstream, therefore C++. So why aren't you doing things the easy way? o__O


for (int i = 0; i < 17; i++) {
// if you're going to hard-code a line length to read in,
// you may as well hard-code an array size.
for (int j = 0; j < 17; j++) {
char commaBucket; // commas go in here!
// (and newlines, too. How convenient.)
MAP >> TileSrc[j][i] >> commaBucket;
// Of course, this will put the number as it appears to you
// in text, into the array. I assume you realize that the
// way you were doing it was going to put in ASCII values for
// the characters.
// Or you could always just use chars for TileSrc...
}
}




Left as an exercise: Use std::vector<std::vector<whatever> > for TileSrc; allocate TileSrc while reading the file; detect newlines in order to know when to stop one row and start the next. Notice that you aren't even limited to rectangular maps that way. :)

Share this post


Link to post
Share on other sites
You're reading a 7x7 matrix from the file, counting with the comas you have to read 33 characters at a time, for string termination a last space is left to store a 0, so it adds up to 34 spaces.

I don't see anywhere in your code you null terminating (putting the 0 at the end of the string) the strings, so when you try to output them, it's not only goind to output the string but since there is no null termination, is going to read random crap in memory until it finds a 0 or seg faults.

That might be the problem.

Share this post


Link to post
Share on other sites
Quote:
Original post by Shadow Wolf
*** Source Snippet Removed ***


Shadow Wolf that is great ! But i found out we have to use atoi() on that buffer.

I can see i have come to the right place ;]

And Zahlman, whats this vector stuff...hey it sthe beginners forum so i may as well ask ;]

WhiteRabbit: Your right ;]

Share this post


Link to post
Share on other sites
Quote:

whats this vector stuff...hey it sthe beginners forum so i may as well ask


About 67,800 web pages want to tell you that it's basically a wrapper for arrays that automatically reallocates memory and moves stuff around as needed when you need more space than is currently available. And does it at least as efficiently as anything you could write manually to do the job. (And with a little care, should be as fast, and use only a little bit more space, in release mode as using a plain array, even when you know exactly what size you need and don't need to change it over time.)

Share this post


Link to post
Share on other sites
Vectors are better than arrays because you don't need to know how many elements you'll be adding when you declare (or allocate for, in the case of pointers) them. If you know how big your array will be at compile-time, I'd generally advise to stick with arrays - they're easier to get your head around if you're new to the language for one thing, and can slow things down in some cases too.

Share this post


Link to post
Share on other sites
I read up on vectors a bit, i can honestly say that im confused. I dont find it necessary to use a vector for this application as my grid will always be of static size (17*17). What do you think ?

Actually i found a much better way of doing this.



struct MAP
{
int TileSrc[17][17];
};

std::ifstream fin("map.lr", ios_base::in | ios_base::binary);
fin.read((char*)map, sizeof(MAP)); //fill map array
fin.close();





after saving it in binary of course, ive already posted too much code here.

[Edited by - jsloan on September 12, 2004 3:31:57 PM]

Share this post


Link to post
Share on other sites

This topic is 4840 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this