So I'm developing tile engine for a game built-in C++. as part of this, I want to store and load tiles from a .txt file saved in the game's directory.
this code saves a level
void LevelManager::SaveToFile(char * FileName)
{
ofstream File(FileName);
File.clear();
for (unsigned y = 0; y < 300; y++) {
for (unsigned x = 0; x < 300; x++) {
File << TileGrid[x][y].PhysicsNumber << " ";
File << TileGrid[x][y].GT.TopLeft << " ";
File << TileGrid[x][y].GT.TopRight << " ";
File << TileGrid[x][y].GT.BottomLeft << " ";
File << TileGrid[x][y].GT.BottomRight << " ";
}
File << "\n";
}
File.close();
}
and then the following code reads the file
void LevelManager::LoadFromFile(char * FileName)
{
ifstream infile;
int y = 0;
int x = 0;
int counter = 1;
infile.open(FileName);
while (y < 300) {
char Current = 0;
infile.read(&Current, 1);
if (Current == 10) {
y++;
x = 0;
}
else if (Current == 32) {
counter++;
if (counter > 5) counter = 1;
x++;
}
else if (counter == 1) {
TileGrid[x][y].PhysicsNumber = (TileGrid[x][y].PhysicsNumber * 10) + Current - 48;
}
else if (counter == 2) {
TileGrid[x][y].GT.TopLeft = (TileGrid[x][y].GT.TopLeft * 10) + Current - 48;
}
else if (counter == 3) {
TileGrid[x][y].GT.TopRight = (TileGrid[x][y].GT.TopRight * 10) + Current - 48;
}
else if (counter == 4) {
TileGrid[x][y].GT.BottomLeft = (TileGrid[x][y].GT.BottomLeft * 10) + Current - 48;
}
else if (counter == 5) {
TileGrid[x][y].GT.BottomRight = (TileGrid[x][y].GT.BottomRight * 10) + Current - 48;
}
}
infile.close();
}
Visual Studio is giving me this error "Access Violation writing Location 0x00B0A654"
research online suggests that I'm reading data that doesn't exist but I'm unsure on how I can fix that.
Edit: forgot to mention that the error only occurs when writing the saving code.
Like other people already stated, a debugger is a great help in case of an error. Fortunately you have already found the error.
Nevertheless, I think your code can be simplified. Overly complicated code is often a frustrating source of errors, and so it's always a major goal to keep the code as simple as possible. Your LoadFromFile()
function is really complicated; I'm having a hard time to understand what's happening there. And you probably had too... like you said, the error was somewhere inside of your Current
, x
and so on declaration and if
's.
Here is a much simpler and much more understandable version of your LoadFromFile()
/ SaveToFile()
functions.
void LevelManager::SaveToFile( char * FileName ) {
try {
std::ofstream file( FileName );
file.clear();
for(unsigned y = 0; y < 300; y++) {
for(unsigned x = 0; x < 300; x++) {
file << TileGrid[x][y].PhysicsNumber << "\n";
file << TileGrid[x][y].GT.TopLeft << "\n";
file << TileGrid[x][y].GT.TopRight << "\n";
file << TileGrid[x][y].GT.BottomLeft << "\n";
file << TileGrid[x][y].GT.BottomRight << "\n";
}
}
file.close();
} catch(...) {} //TODO: catch & evaluate file errors
}
void LevelManager::LoadFromFile( char * FileName ) {
try {
std::ifstream file( FileName );
for(unsigned y = 0; y < 300; y++) {
for(unsigned x = 0; x < 300; x++) {
file >> TileGrid[x][y].PhysicsNumber;
file >> TileGrid[x][y].GT.TopLeft;
file >> TileGrid[x][y].GT.TopRight;
file >> TileGrid[x][y].GT.BottomLeft;
file >> TileGrid[x][y].GT.BottomRight;
}
}
file.close();
} catch(...) {} //TODO: catch & evaluate file errors
}
This time, the LoadFromFile()
is much easier to understand. And you could even simplify this more by writing an operator, which pushes/pops a complete TileGrid element to/from a stream.
I have roughly tested this code in a test environment; please let me know if you need the whole file.