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

Started by
11 comments, last by Temrek 18 years, 5 months ago
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?
Advertisement
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



Network EngineerVolition Inc.
I have tried that strtok did not like it :(
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)
------ XYE - A new edition of the classic Kye
Unfortunatly that does not work :(
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.45something model/path/model.ext 123.45 123.45 123.45 123.45 effect/path/effect.ext 123.45 123.45 123.45something model/path/model.ext 123.45 123.45 123.45 123.45 effect/path/effect.ext 123.45 123.45 123.45FILEEND

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
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; ?

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.

// badint 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.// goodstruct 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.
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.
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.

This topic is closed to new replies.

Advertisement