Can't compare char strings.

Hello :D

I've a weird problem and I hope you can help me:

I have two char* that have the same data in (hypothetically).

1
2
3
4
std::vector<char*> Buff;
Buff = Split(Line, '.');
char* A = "data", B;
B = Buff.at(0)


Where Split is a function that I made to split a string (Line in this case) into a char* vector, this string contains a line from a file. Line is char* too. The weird problem is when Buff data stored in its 0 position is given to B... because B is equal to A (hypothetically) but when this is compared to do certain functions they doesn't match!

Here an example:

1
2
3
4
5
6
7
8
std::vector<char*> Buff;
Buff = Split(Line, '.');
char* A = "map", B;
B = Buff.at(0) // Buff.at(0) should be "map" and is apparently "map"

if (A == B) { // A and B should be the same, but its not!!?
    // do some things...
}


When I view this event in a debugger I put A and B to watch, but this appear:
A = "map"
B = 0x821220 "map" (or any else hex value before "map" or any else string)

I'll explain the Split function here in case Split function could be the problem:

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
std::vector<char*> Split(char* String, char Delimiter) {
	std::vector<char*> Ret;
	std::string Tmp = String;
	int lng = Tmp.size();
	char Temp[lng];
	strcpy(Temp, String);
	std::string Itm;
	for (int i = 0; i <= lng; i++) {
		if (Temp[i] != Delimiter) {
			Itm = Itm + Temp[i];
		} else {
			Ret.push_back(StringToChar(Itm));
			Itm = "";
		}
	}
	if (Ret.empty()) {
		Ret.push_back(String);
	} else {
		Ret.push_back(StringToChar(Itm));
	}
	return Ret;
}

char* StringToChar(std::string str) {
	char *a=new char[str.size()+1];
	a[str.size()]=0;
	memcpy(a,str.c_str(),str.size());
	return a;
}


And the real code of the situation with "A" and "B":

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
void Map::LoadMap(char* FilePath, bool LoadSettings = true) {
	std::ifstream FS;
	char* Line;
	std::string L;
	FS.open(FilePath);
	if (FS.is_open()) {
		while ( FS.good() )
	    {
	    	char* Cmd;
	    	std::vector<char*> Buff;
	    	std::getline(FS, L);
	    	Line = StringToChar(L);
	    	Buff = Split(Line, '.');
	    	if (Buff.empty()) { continue; }
	    	Cmd = Buff.at(0);
    		if (Cmd == "map") {
    			// Do something...
    		}
    		
    		if (Cmd == "point") {
    			// Do something...
    		}
    		
    		if (Cmd == "object") {
    			// Do something...
    		}
    		
    		if (Cmd == "data") {
    			// Do something...
    		}
	    }
	    FS.close();
	}
}


NOTE: I didn't use switch to compare Cmd because I want it separately for easier debugging.

Is there something wrong with my codes?? or what happened here with those hex values before the string in my variables??

Thanks in advance.
> have two char* that have the same data in (hypothetically).
1
2
3
std::vector<char*> Buff;
Buff = Split(Line, '.');
char* A = "data", B;
B is not a char* but simply a char
Also, A should be const char*

> A == B
If you do defined B as a pointer, then you are comparing pointers.
If you want to compare the c-strings, use `strcmp()'

However I would recommend to use std::string instead.


> I didn't use switch to compare Cmd because I want it separately for easier debugging.
You can't use switch because you are not comparing against an integer value.
It wouldn't made debugging easier.


>
1
2
3
4
	std::string Tmp = String;
	int lng = Tmp.size();
	char Temp[lng]; //illegal
	strcpy(Temp, String);
o_O ¿why do you think that's a good idea?
Last edited on
Thanks!

Well, looking at the code you showed me, I do the next modification:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
std::vector<char*> Split(char* String, char Delimiter) {
	std::vector<char*> Ret;
	std::string Tmp = String, Itm;
	for (int i = 0; i <= Tmp.size(); i++) {
		if (Tmp.c_str()[i] != Delimiter) {
			Itm = Itm + Tmp.c_str()[i];
		} else {
			Ret.push_back(StringToChar(Itm));
			Itm = "";
		}
	}
	if (Ret.empty()) {
		Ret.push_back(String);
	} else {
		Ret.push_back(StringToChar(Itm));
	}
	return Ret;
}


But I can't get the right way to successfully compare A and B ... A should be a const char*, That's right, but A in this example is just an example. The real A and B is like this:

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
void Map::LoadMap(char* FilePath, bool LoadSettings = true) {
	std::ifstream FS;
	char* Line;
	std::string L;
	FS.open(FilePath);
	if (FS.is_open()) {
		while ( FS.good() )
	    {
	    	char* Cmd;
	    	std::vector<char*> Buff;
	    	std::getline(FS, L);
	    	Line = StringToChar(L);
	    	Buff = Split(Line, '.');
	    	if (Buff.empty()) { continue; }
	    	Cmd = Buff.at(0); // This is B
    		if (Cmd == "map") { // "map" is A
    			// Do something...
    		}
    		
    		if (Cmd == "point") {
    			// Do something...
    		}
    		
    		if (Cmd == "object") {
    			// Do something...
    		}
    		
    		if (Cmd == "data") {
    			// Do something...
    		}
	    }
	    FS.close();
	}
}


And well, I could use always strings and all this problems will dissappear (I use strings in all the code before and there was no problems). But I want to use char* instead strings because all this code is for a static library and I'll use it in a variety of software but is a bit awkward to use always strings also in the software that I develop with this static library.

The main question is: why the char* vector have hex values before the real value? in example - Buff.at(0) = 0x821220 "map" but Buff is a char* vector! and why Buff.at(0) being 0x821220 "map" is not the same as just "map"?

Remembering that Buff is a char* vector and it gets all its values with a function called Split:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
std::vector<char*> Split(char* String, char Delimiter) {
	std::vector<char*> Ret;
	std::string Tmp = String, Itm;
	for (int i = 0; i <= Tmp.size(); i++) {
		if (Tmp.c_str()[i] != Delimiter) {
			Itm = Itm + Tmp.c_str()[i];
		} else {
			Ret.push_back(StringToChar(Itm));
			Itm = "";
		}
	}
	if (Ret.empty()) {
		Ret.push_back(String);
	} else {
		Ret.push_back(StringToChar(Itm));
	}
	return Ret;
}


Why Split returns a char* vector that values cannot be compared with a normal char* string? This really bothers me...

Thanks in advance.
¿what part of `you are comparing pointers' you didn't understand?
Again, use `strcmp()' to compare the c-strings.


> But I want to use char* instead strings because all this code is for a static library
> and I'll use it in a variety of software
> but is a bit awkward to use always strings also in the software
> that I develop with this static library.
¿? I don't understand your reasoning.
Besides, you've got a lot of yo-yo code.


> why the char* vector have hex values before the real value? in example - Buff.at(0) = 0x821220 "map"
The debugger is trying to be helpful
The pointers has the value `0x821220'. At that memory address you can read the `map' string.


Also, take a look at http://www.cplusplus.com/faq/sequences/strings/split/#string-find_first_of
To the OP:

You've declared Cmd to be char *. That means it's a pointer to character. A pointer is just an address in memory, so you're basically just storing a number in Cmd. That number gives the address of the memory where your string is stored.

By convention, memory addresses are usually given as hex numbers, so that is why your debugger is displaying a hex value. Since it's a char*, the debugger is also being helpful and displaying the contents of the memory at the address that's stored in that pointer, interpreting that data as characters.

When you do the comparison Cmd == "data", you are not comparing the contents of the strings. You are comparing the memory address stored in Cmd (because Cmd is a pointer) with the memory address which the compiler has allocated for the string literal "data". In other words, you're comparing two hex numbers.

As others have already said, you need to use the standard library functions which do the job of comparing the strings pointed to by two character pointers, e.g. strcmp().

If you're going to insist on using C-style character arrays to hold strings, you really need to go back to your textbooks and read up on arrays, pointers, and strings, because I don't think you really understand them yet.
That explanation was really helpful, thanks MikeyBoy & ne555. I can now understand where my error was and why. According to all this information now I was able to finish my work :)

I'll have in mind all your findings to enhance my code.
You're welcome. Glad it helped :)
Topic archived. No new replies allowed.