Sign in to follow this  
Temrek

char array is being assigned a vlaue when it should not.

Recommended Posts

Temrek    122
I am trying to read a file and it works well, but when I am trying to save the data from the file in RAM things get screwy, namelet the colitmap array is being assigned a vlue when it COULD not. I am using c++.
char CrntPlace[2048];
    char* templine = "hi";
        ReadLine(mapfile, line);
        int firstline = 0;
    while (strcmp(templine, "FILEEND") != 0)
    {
     
     templine = strtok(line," ");
     
    //load Colitmap
    if (firstline < 1)
    {
    Colitmap = templine;
    }
    templine = strtok (NULL, " ");
    // Load Model Path
    Model[firstline].String = templine;
        // Load ModelX 
    templine = strtok (NULL, " ");
    MdlRelX[firstline] = (float(templine[0]) -48.0f)  * 100.0f;
    MdlRelX[firstline] = MdlRelX[firstline] + (float(templine[1]) -48.0f) * 10.0f;
    MdlRelX[firstline] = MdlRelX[firstline] + (float(templine[2]) -48.0f);
    MdlRelX[firstline] = MdlRelX[firstline] + (float(templine[4]) -48.0f) * 0.1f;
    MdlRelX[firstline] = MdlRelX[firstline] + (float(templine[5]) -48.0f) * 0.01f;
    // Load ModelY
    templine = strtok (NULL, " ");
    MdlRelY[firstline] = (float(templine[0]) -48.0f)  * 100.0f;
    MdlRelY[firstline] = MdlRelY[firstline] + (float(templine[1]) -48.0f) * 10.0f;
    MdlRelY[firstline] = MdlRelY[firstline] + (float(templine[2]) -48.0f);
    MdlRelY[firstline] = MdlRelY[firstline] + (float(templine[4]) -48.0f) * 0.1f;
    MdlRelY[firstline] = MdlRelY[firstline] + (float(templine[5]) -48.0f) * 0.01f;
    // Load ModelZ
    templine = strtok (NULL, " ");
    MdlRelZ[firstline] = (float(templine[0]) -48.0f)  * 100.0f;
    MdlRelZ[firstline] = MdlRelZ[firstline] + (float(templine[1]) -48.0f) * 10.0f;
    MdlRelZ[firstline] = MdlRelZ[firstline] + (float(templine[2]) -48.0f);
    MdlRelZ[firstline] = MdlRelZ[firstline] + (float(templine[4]) -48.0f) * 0.1f;
    MdlRelZ[firstline] = MdlRelZ[firstline] + (float(templine[5]) -48.0f) * 0.01f;
    // Load ModelScale
    templine = strtok (NULL, " ");
    MdlScale[firstline] = (float(templine[0]) -48.0f)  * 100.0f;
    MdlScale[firstline] = MdlScale[firstline] + (float(templine[1]) -48.0f) * 10.0f;
    MdlScale[firstline] = MdlScale[firstline] + (float(templine[2]) -48.0f);
    MdlScale[firstline] = MdlScale[firstline] + (float(templine[4]) -48.0f) * 0.1f;
    MdlScale[firstline] = MdlScale[firstline] + (float(templine[5]) -48.0f) * 0.01f;
    // Load FX Path
        templine = strtok (NULL, " ");
    FX[firstline].String = templine;
           // Load FXX 
    templine = strtok (NULL, " ");
    FXRelX[firstline] = (float(templine[0]) -48.0f)  * 100.0f;
    FXRelX[firstline] = FXRelX[firstline] + (float(templine[1]) -48.0f) * 10.0f;
    FXRelX[firstline] = FXRelX[firstline] + (float(templine[2]) -48.0f);
    FXRelX[firstline] = FXRelX[firstline] + (float(templine[4]) -48.0f) * 0.1f;
    FXRelX[firstline] = FXRelX[firstline] + (float(templine[5]) -48.0f) * 0.01f;
    // Load FXY
    templine = strtok (NULL, " ");
    FXRelY[firstline] = (float(templine[0]) -48.0f)  * 100.0f;
    FXRelY[firstline] = FXRelY[firstline] + (float(templine[1]) -48.0f) * 10.0f;
    FXRelY[firstline] = FXRelY[firstline] + (float(templine[2]) -48.0f);
    FXRelY[firstline] = FXRelY[firstline] + (float(templine[4]) -48.0f) * 0.1f;
    FXRelY[firstline] = FXRelY[firstline] + (float(templine[5]) -48.0f) * 0.01f;
    // Load FXZ
    templine = strtok (NULL, " ");
    FXRelZ[firstline] = (float(templine[0]) -48.0f)  * 100.0f;
    FXRelZ[firstline] = FXRelZ[firstline] + (float(templine[1]) -48.0f) * 10.0f;
    FXRelZ[firstline] = FXRelZ[firstline] + (float(templine[2]) -48.0f);
    FXRelZ[firstline] = FXRelZ[firstline] + (float(templine[4]) -48.0f) * 0.1f;
    FXRelZ[firstline] = FXRelZ[firstline] + (float(templine[5]) -48.0f) * 0.01f;
   
   cout << Colitmap << endl;
        ReadLine(mapfile, line);
        templine = line;
    firstline++;
    }
the code under the if that sets the colitmap is only run once, that I have checked. Help please?

Share this post


Link to post
Share on other sites
TtDTtW    152
Quote:
Original post by Temrek
char* templine = "hi";

Just me thinking, and someone should varify, but I think it's this line right here. You're declaring a char pointer to something that really doesn't exist. (A tempory static storage of size 3 if I recall how the compiler works)
char templine[255];

Which will give you more space and probably won't overrun any other char* buffers you have. If you need it bigger just increase the number.

Just my thinking...

- Topher



Share this post


Link to post
Share on other sites
Vexorian    152
The top should be changed

char* templine = new char[Some size you want];
strcpy(templine,"hi")








don't forget to delete[] templine before the other assigment to that variable

edit: No this won't work, couldn't you use 2 different variables one for the first templine other for the templines returned byt strtok?

edit 2: I think that a do while would work better for this








char CrntPlace[2048];
char* templine;
ReadLine(mapfile, line);
int firstline = 0;
do
{

templine = strtok(line," ");

//load Colitmap
if (firstline < 1)
{
Colitmap = templine;
}
templine = strtok (NULL, " ");
// Load Model Path
Model[firstline].String = templine;
// Load ModelX
templine = strtok (NULL, " ");
MdlRelX[firstline] = (float(templine[0]) -48.0f) * 100.0f;
MdlRelX[firstline] = MdlRelX[firstline] + (float(templine[1]) -48.0f) * 10.0f;
MdlRelX[firstline] = MdlRelX[firstline] + (float(templine[2]) -48.0f);
MdlRelX[firstline] = MdlRelX[firstline] + (float(templine[4]) -48.0f) * 0.1f;
MdlRelX[firstline] = MdlRelX[firstline] + (float(templine[5]) -48.0f) * 0.01f;
// Load ModelY
templine = strtok (NULL, " ");
MdlRelY[firstline] = (float(templine[0]) -48.0f) * 100.0f;
MdlRelY[firstline] = MdlRelY[firstline] + (float(templine[1]) -48.0f) * 10.0f;
MdlRelY[firstline] = MdlRelY[firstline] + (float(templine[2]) -48.0f);
MdlRelY[firstline] = MdlRelY[firstline] + (float(templine[4]) -48.0f) * 0.1f;
MdlRelY[firstline] = MdlRelY[firstline] + (float(templine[5]) -48.0f) * 0.01f;
// Load ModelZ
templine = strtok (NULL, " ");
MdlRelZ[firstline] = (float(templine[0]) -48.0f) * 100.0f;
MdlRelZ[firstline] = MdlRelZ[firstline] + (float(templine[1]) -48.0f) * 10.0f;
MdlRelZ[firstline] = MdlRelZ[firstline] + (float(templine[2]) -48.0f);
MdlRelZ[firstline] = MdlRelZ[firstline] + (float(templine[4]) -48.0f) * 0.1f;
MdlRelZ[firstline] = MdlRelZ[firstline] + (float(templine[5]) -48.0f) * 0.01f;
// Load ModelScale
templine = strtok (NULL, " ");
MdlScale[firstline] = (float(templine[0]) -48.0f) * 100.0f;
MdlScale[firstline] = MdlScale[firstline] + (float(templine[1]) -48.0f) * 10.0f;
MdlScale[firstline] = MdlScale[firstline] + (float(templine[2]) -48.0f);
MdlScale[firstline] = MdlScale[firstline] + (float(templine[4]) -48.0f) * 0.1f;
MdlScale[firstline] = MdlScale[firstline] + (float(templine[5]) -48.0f) * 0.01f;
// Load FX Path
templine = strtok (NULL, " ");
FX[firstline].String = templine;
// Load FXX
templine = strtok (NULL, " ");
FXRelX[firstline] = (float(templine[0]) -48.0f) * 100.0f;
FXRelX[firstline] = FXRelX[firstline] + (float(templine[1]) -48.0f) * 10.0f;
FXRelX[firstline] = FXRelX[firstline] + (float(templine[2]) -48.0f);
FXRelX[firstline] = FXRelX[firstline] + (float(templine[4]) -48.0f) * 0.1f;
FXRelX[firstline] = FXRelX[firstline] + (float(templine[5]) -48.0f) * 0.01f;
// Load FXY
templine = strtok (NULL, " ");
FXRelY[firstline] = (float(templine[0]) -48.0f) * 100.0f;
FXRelY[firstline] = FXRelY[firstline] + (float(templine[1]) -48.0f) * 10.0f;
FXRelY[firstline] = FXRelY[firstline] + (float(templine[2]) -48.0f);
FXRelY[firstline] = FXRelY[firstline] + (float(templine[4]) -48.0f) * 0.1f;
FXRelY[firstline] = FXRelY[firstline] + (float(templine[5]) -48.0f) * 0.01f;
// Load FXZ
templine = strtok (NULL, " ");
FXRelZ[firstline] = (float(templine[0]) -48.0f) * 100.0f;
FXRelZ[firstline] = FXRelZ[firstline] + (float(templine[1]) -48.0f) * 10.0f;
FXRelZ[firstline] = FXRelZ[firstline] + (float(templine[2]) -48.0f);
FXRelZ[firstline] = FXRelZ[firstline] + (float(templine[4]) -48.0f) * 0.1f;
FXRelZ[firstline] = FXRelZ[firstline] + (float(templine[5]) -48.0f) * 0.01f;

cout << Colitmap << endl;
ReadLine(mapfile, line);
templine = line;
firstline++;
} while (strcmp(templine, "FILEEND") != 0)


Share this post


Link to post
Share on other sites
Enigma    1410
This is the problem of using char *s to represent text. You would need to allocate memory and copy the data into it, not just assign pointers. Instead you should be using std::string to represent text. Assuming that your data file looks like:
collisionMap model/path/model.ext 123.45 123.45 123.45 123.45 effect/path/effect.ext 123.45 123.45 123.45
something model/path/model.ext 123.45 123.45 123.45 123.45 effect/path/effect.ext 123.45 123.45 123.45
something model/path/model.ext 123.45 123.45 123.45 123.45 effect/path/effect.ext 123.45 123.45 123.45
FILEEND

Your loading code could look something like:
std::ifstream file("filename.ext");
bool readCollisionMap = false;
std::vector< Thing > things;
while (true)
{
std::string collisionMap;
file >> collisionMap;
if (collisionMap == "FILEEND")
{
break;
}
if (!readCollisionMap)
{
Colitmap = collisionMap;
readCollisionMap = true;
}
Thing thing;
file >> thing.model.path;
file >> thing.model.x;
file >> thing.model.y;
file >> thing.model.z;
file >> thing.model.scale;
file >> thing.effect.path;
file >> thing.effect.x;
file >> thing.effect.y;
file >> thing.effect.z;
things.push_back(Thing);
}

Where Colitmap, thing.model.path and thing.effect.path are std::strings.

Enigma

Share this post


Link to post
Share on other sites
Temrek    122
That piece of code looks promising (much shorter then my newb code :P ) but I wonder what the thing in the vector is suposed to be as well as the Thing thing; ?

Share this post


Link to post
Share on other sites
Zahlman    1682
The suggestion is that instead of having parallel arrays whateverX[numberOfThings], whateverY[numberOfThings] etc., that you create a struct to hold all of the bits for a given 'Thing', and then have a single array of those structures which are read in one at a time.


// bad
int myXValues[100];
int myYValues[100];
// Now I have to keep those values in sync with each other; if I am moving stuff
// around in one array, I need to do the same things to the other arrays, and it
// quickly becomes very difficult to keep straight.

// good
struct thingWithXAndYValues {
int x;
int y;
}
thingWithXAndYValues myThings[100];
// Now bits of data that are relevant to each other are held together. The data
// has real *structure* to it (hence struct), and will be much easier to manage.


In Enigma's sample, Thing is just the struct name, and "Thing thing;" is simply a variable declaration for a variable named "thing" of type "Thing".

The other suggestion is to use std::vector instead of a statically-sized array of Things. This is for basically all the same reasons that one would use std::string instead of a char pointer to deal with text: memory is properly managed and resized for you - you don't have to worry about buffer overruns, knowing what size of thing you need, handling who will allocate or deallocate memory, etc.

Share this post


Link to post
Share on other sites
Temrek    122
Okay, I am trying to get this working but it just refuses to.


std::ifstream file(path);
bool readCollisionMap = false;
//std::vector< Thing > things;
file.ignore(500,'/n');

int times = 0;
while (true)
{
std::string collisionMap;
file >> collisionMap;
cout << collisionMap << endl;
if (collisionMap == "FILEEND" || times == 9)
{
break;
}
if (!readCollisionMap)
{
Colitmap = collisionMap;
readCollisionMap = true;
}
file >> TileModels[times].Path;
cout << TileModels[times].Path << endl;
file >> TileModels[times].x;
file >> TileModels[times].y;
file >> TileModels[times].z;
file >> TileModels[times].scale;
file >> TileFX[times].Path;
file >> TileFX[times].x;
file >> TileFX[times].y;
file >> TileFX[times].z;
times++;
//things.push_back(Thing);
}

file.close();

the thing crashes without giving any output that I can see, also I cant find anywhere what push_back is supposed to do.

Share this post


Link to post
Share on other sites
Zahlman    1682

file.ignore(500,'/n');


You want \n of course :)


int times = 0;
while (true) {
std::string collisionMap;
file >> collisionMap;


This reads a single word (up to the next whitespace) into the collisionMap string. If you wanted to grab a whole line, that could be your problem. Oh, you should be using the "times" (if at all; you won't need to with a std::vector) in the loop condition. Actually, you should just make a for loop in that case; it is OK to break out of a for loop.


if (!readCollisionMap)
{
Colitmap = collisionMap;
readCollisionMap = true;
}


So you want to remember this value for just the first line? What exactly is this indicating? What exactly does your file look like?

Quote:

file >> TileModels[times].Path;
cout << TileModels[times].Path << endl;
file >> TileModels[times].x;
file >> TileModels[times].y;
file >> TileModels[times].z;
file >> TileModels[times].scale;
file >> TileFX[times].Path;
file >> TileFX[times].x;
file >> TileFX[times].y;
file >> TileFX[times].z;


This part will be fine IF the data at that point in the line can be interpreted as the right type for those variables. If you have some text there where a number is expected, the stream will get stuck. You need to detect this condition, and 'reset' the stream (and also 'ignore' the bad data, because it is not removed from the stream and would re-trigger the problem) when it happens.

And please use the structs.


file.close();


Not needed (though not harmful); files are implicitly close()d at in their destructors (i.e. at the end of the variable scope)

Quote:
also I cant find anywhere what push_back is supposed to do.


Sigh.

Share this post


Link to post
Share on other sites
Temrek    122
The file looks exactly like engima figured out (except replace something with NULL).

I got it to work better now, but it does not work as it is supposed to.

BTW I am using structs.

It never seems to detect eof.


if (file.eof() == true || times == 9)
{
break;
}


The output I get is right except it does not stop when it is supposed to.

Share this post


Link to post
Share on other sites
Zahlman    1682
When you say "replace something with NULL", do you mean that the actual text "NULL" appears in your file, or that there is *nothing there* (i.e. the line starts with the file name)? That way would explain everything: what happens is that the file name gets read when it looks for "collisionMap", and then the first number gets read (as text) when it looks for the file name, and then eventually it reads the file name on the *next* line as the last number (because that's the next token in the file when it gets to that point).

I would strongly suggest that you (a) put the 'collisionMap' label on its own line (assuming it's really needed at all?) and (b) be more careful about how you handle reading it - you should not "try" to read it in each line.

As for eof(), it does not return true until you have already tried to read past the end. The stream does not magically know "there is no more data" until it tries to read something and finds out that there is no more data. You will need to Think(TM) to design around this.

Share this post


Link to post
Share on other sites
Temrek    122
I meant I write NULL in the file (that data is read but not used, hence null, I could do without not actually writing anything though).

By the way I got it to work completly as I want to, thanks for all your help!

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