Sign in to follow this  
Sigutis

C++ mysticism while reading binary

Recommended Posts

Now, I have to say I am screwed here. I am writing a map loading feature for my game. It's still in console application stage. The bug appears to be in the waypoint part. The idea is - every monster has 5 positions to walk. Just to look he's busy ;) . First monster_number is loaded, then the loop ( constantly 5 times) loads coordinates for each waypoint into monster_waypoint;
in
is an ifstream object.
p
is just an integer variable used as file position.
for (N=0;N<5;N++){
  for (n=0;n<monster_number;n++){	
    p+=10;
    in.seekg(p);								
    in >> monster_waypoint[N][n].x;
    p+=10;
    in.seekg(p);	
    in >> monster_waypoint[N][n].y;
  }
}
Now, I tried to load my example map - everything looks to be loaded fine. This is fallowed by active object loading, witch is not important in the case.
p+=10;
in.seekg(p);										in >> active_obj_number;
But if I want to check the second monsters fifth waypoints x value (phew) with
cout << monster_waypoint[4][1].x;
Program does not crash but rather ignores code that goes after it. Press any key to continue... The strange part is that if I put
 cout << monster_waypoint[4][0].x; 
BEFORE reading active_obj_number it works perfect. It prints correct value. Also if I ask to print something like
cout << monster_waypoint[3][1].x;
it works fine. I assure there is nothing wrong with the binary file itself.

Share this post


Link to post
Share on other sites
You're not supposed to use the >> operator for binary access. Use read() instead.

BTW, I don't understand why you are even bothering with p. When you read data from the file, the file advances it's internal position automatically.

It might also help if you post more code. There might be some problems with the way you are initializing things.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sigutis
I assure there is nothing wrong with the binary file itself.
This isn't directly an answer to what you were asking, but doing binary I/O with std::iostreams is really asking for trouble. They are designed to work with textual data, and even setting ios::binary does not do what you might think.

Share this post


Link to post
Share on other sites
->Bregma
Using the "read" function is what I though. I'll try it .

->Gage64
Yes, I can't remember why I started using them "p" in the first place

->nhatkthanh
Not really. Thats how I do it. Must be my twisted brain. I am thinking backwards or something :>.

->swiftcoder
I'll keep that in mind

Share this post


Link to post
Share on other sites
Quote:
Original post by Sigutis
->nhatkthanh
Not really. Thats how I do it. Must be my twisted brain. I am thinking backwards or something :>.


Each monster has waypoints, so the natural OO way of doing things is to add the waypoint data (array of 5 positions) as a data member of the Monster. Then when you iterate over monsters to .update() them, the update for a given Monster looks at its own waypoints.

How are you representing a waypoint, anyway? How big are you expecting the .x and .y fields to be, and why?

Share this post


Link to post
Share on other sites
I do not have the monster class yet.

struct koords{
unsigned x,y;
};

To represent the coordinates.


koords *monster_waypoint[4];

My map class member.

After loading monster_number:

monster_waypoint[0] = new koords[monster_number];
monster_waypoint[1] = new koords[monster_number];
monster_waypoint[2] = new koords[monster_number];
monster_waypoint[3] = new koords[monster_number];
monster_waypoint[4] = new koords[monster_number];


And so I store all monster first waypoint in monster_waypoint[0]
Second in monster_waypoint[1] etc.
I can access the x positions of 1st monster :
monster_waypoint[0][0].x
monster_waypoint[1][0].x
monster_waypoint[2][0].x
monster_waypoint[3][0].x
monster_waypoint[4][0].x


x and y are unsigned integers but I give 10 symbol space fields in the files for each number.

Share this post


Link to post
Share on other sites
I create data file by simulating upcoming map editor using this program.

#include <fstream>
#include <string>

using namespace std;

struct vector {
int x,y,z;
};
int main(){
string map_name="textures/test.jpg";
ofstream out("test.psm", ios::binary);
//texture
out.seekp(0);
out << map_name;
//light number
out.seekp(30);
out << 3;
//light ranges
out.seekp(40);
out << 22;
out.seekp(50);
out << 33;
out.seekp(60);
out << 3310;
//light color
out.seekp(70);
out << 3231;
out.seekp(80);
out << 123;
out.seekp(90);
out << 2210;
//light position
vector Vector1,Vector2,Vector3;
Vector1.x=1;
Vector1.y=2;
Vector1.z=3;

Vector2.x=4;
Vector2.y=5;
Vector2.z=6;

Vector3.x=7;
Vector3.y=8;
Vector3.z=9;

out.seekp(100);
out << Vector1.x;
out.seekp(110);
out << Vector1.y;
out.seekp(120);
out << Vector1.z;
out.seekp(130);
out << Vector2.x;
out.seekp(140);
out << Vector2.y;
out.seekp(150);
out << Vector2.z;
out.seekp(160);
out << Vector3.x;
out.seekp(170);
out << Vector3.y;
out.seekp(180);
out << Vector3.z;
//solid obj number
out.seekp(190);
out << 4;
//solid obj rotation
out.seekp(200);
out << 44;
out.seekp(210);
out << 33;
out.seekp(220);
out << 33;
out.seekp(230);
out << 22;
//solid obj scaling
out.seekp(240);
out << 440;
out.seekp(250);
out << 330;
out.seekp(260);
out << 330;
out.seekp(270);
out << 220;
//solid obj position
out.seekp(280);
out << 999;
out.seekp(290);
out << 888;
out.seekp(300);
out << 777;
out.seekp(310);
out << 666;

out.seekp(320);
out << 555;
out.seekp(330);
out << 444;
out.seekp(340);
out << 333;
out.seekp(350);
out << 222;
//monster number
out.seekp(360);
out << 2;
//monsters
out.seekp(370);
out << 1;
out.seekp(380);
out << 2;
out.seekp(390);
out << 3;
out.seekp(400);
out << 4;
out.seekp(410);
out << 5;

out.seekp(420);
out << 11;
out.seekp(430);
out << 22;
out.seekp(440);
out << 33;
out.seekp(450);
out << 44;
out.seekp(460);
out << 55;
//monster ranges
out.seekp(470);
out << 123;
out.seekp(480);
out << 321;
//monster position
out.seekp(490);
out << 4444;
out.seekp(500);
out << 3333;

out.seekp(510);
out << 11111;
out.seekp(520);
out << 22222;
//monster waypoints
out.seekp(530);
out << 3333;
out.seekp(540);
out << 555;
out.seekp(550);
out << 666;
out.seekp(560);
out << 777;

out.seekp(570);
out << 888;
out.seekp(580);
out << 999;
out.seekp(590);
out << 1233;
out.seekp(600);
out << 3221;

out.seekp(610);
out << 1124;
out.seekp(620);
out << 111;
out.seekp(630);
out << 33333;
out.seekp(640);
out << 5555;

out.seekp(650);
out << 6666;
out.seekp(660);
out << 77777;
out.seekp(670);
out << 8888;
out.seekp(680);
out << 9999;

out.seekp(690);
out << 1213;
out.seekp(700);
out << 3212;
out.seekp(710);
out << 1312;
out.seekp(720);
out << 1111;

//active obj number
out.seekp(730);
out << 1;
//active obj ID's
out.seekp(740);
out << 5;
//active obj positions
out.seekp(750);
out << 640;
out.seekp(760);
out << 480;

out.close();

}

Share this post


Link to post
Share on other sites
Quote:
Original post by Sigutis
I create data file by simulating upcoming map editor using this program.
*** Source Snippet Removed ***


Again, don't use << with binary files. Use write() instead. Also be careful how you write an std::string to a binary file. Probably the best way is to first write the length and then the characters. This makes it easy to read back.

And again, why are you calling seekp()? The ofstream object updates it's internal file position automatically after each call to write(). And what's the point of creating these gaps between the values?

Share this post


Link to post
Share on other sites
I found the >> working as I want only using the "seek" way.
I just thought - give eatch number 10 character space field. Didn't bothered me as long as it worked.

I will rewrite both programs soon. And see what happens.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sigutis
I found the >> working as I want only using the "seek" way.
I just thought - give eatch number 10 character space field. Didn't bothered me as long as it worked.
This is not a binary file - it is a rather borked textual format. Open it up in a text editor, and you should be able to read the contents completely - along with a bunch of garbage from your seeking.

Share this post


Link to post
Share on other sites

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