Please help quickly - FILE I/O

Hey, Something really strange is happening and its really not a good time....

My File I/O was working perfect for the last 2 weeks, now, all of a sudden it is all jumped CRAP and doesnt work correctly. This is the function I use to load the data:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
bool loadUserData()
{
	FILE* fileHandle;
	std::string tmp = "..//Data//Login//USERInfo.txt";
	const char* str = tmp.c_str();
	fileHandle = fopen(str,"r");
	if(fileHandle==NULL)
	{
		return false;
	}
	std::string tmpname = "";
	std::string tmppass = "";
	const char* name = tmpname.c_str();
	const char* pass = tmppass.c_str();
	int health = -1;
	int armour = -1;
	int lives = -1;

	while( true ) {
		Player user;
		int vals_read = fscanf(fileHandle,"%s %s %d:%d:%d",name,pass,&health,&armour,&lives);
		if( vals_read == 5 ) {
			// process the line
			user.setName(name);
			user.setPass(pass);
			user.setHealth(health);
			user.setArmour(armour);
			user.setLives(lives);
			table.Insert(user.getName(),user);
			playerList.Append(user);
			//best case is O(c) for insert depending on if a collision occurs or not
		} else if( feof( fileHandle ) )
			break;
	}
	fclose(fileHandle);
	return true;
}

The file contains this: ANDY tests 100:30:4

I dont get any errors, it seems to work, but the values for name,pass,health,lives,armour are not correct.
for example, name as this weird value:
name = 0x77c2c2e3 "ÃÌÌÌÌÌjhˆ Áwè+±"

health = 1244424

etc...It was working perfectly fine until now...WTF
1
2
3
4
5
6
7
	std::string tmpname = "";
	std::string tmppass = "";
	const char* name = tmpname.c_str();
	const char* pass = tmppass.c_str();
//...

int vals_read = fscanf(fileHandle,"%s %s %d:%d:%d",name,pass,&health,&armour,&lives);


You can't do this. Even if this by some miracle works, you'd be corrupting the heap and it would do VERY BAD THINGS.

name and pass are const. This means you cannot modify what they point to. Therefore passing them to fscanf is totally invalid.

Either ditch the strings and use char arrays, or ditch fscanf and use iostream. strings and fscanf don't play nice together.


Char arrays are likely the least dramatic change:

1
2
3
4
5
6
7
//  std::string tmpname = "";  // get rid of this nonsense
//  std::string tmppass = "";
//  const char* name = tmpname.c_str();
//  const char* pass = tmppass.c_str();

    char name[256];  // do this instead
    char pass[256];  // make sure they're large enough to hold anything the file might have 
Last edited on
Ok but how am I modifying what they point to? Isn't what I am doing just like declaring a new const char* variable and assigning a value to it?
Ok I did what you said, and now while debugging, the char array is full, is that supposed to happen? It is full of gobbledegook apart from where my "string" is
Last edited on
Ok but how am I modifying what they point to?


That's what fscanf does. You give it a bunch of pointers, and it writes data to whatever those pointers point to.

Ideally the compiler should have complained at you and told you what you were doing is illegal. However that's the downside to scanf/printf style formatting functions: they're not typesafe and the compiler can't catch errors like this. So you have to be really careful when using them.

Isn't what I am doing just like declaring a new const char* variable and assigning a value to it?


Not really. You're creating a string, but that string has a length of zero. fscanf can't resize the string to make it longer (it doesn't even know it's a string, it just thinks it's a char pointer), so even if writing data to a const pointer was legal (which it isn't), you'd still be overflowing your string and corrupting the heap.
std::string manages itself, you're not supposed to change its memory like that. Period.
Ok thanks guys
Topic archived. No new replies allowed.