When I use ifstream::get() to get a char*, store it in char[], and compare it to a string it returns false. When I check the debugger, block is the same as the string but with a \0. I tried adding it to the string like "astring\0" and it still returned false. Why? Isn't the string supposed to be null terminated any way?
1 2 3 4 5 6 7 8 9 10 11 12 13
cblock:
c = (char)file.get();
switch ( c )
{
//...
case'[':
file.get( block, 64, ']' );
file.ignore( 64, '\n' );
goto cblock;
//...
}
if ( block == "astring" )
One of the following two cases is happening on line 13 (I'm not sure which)
1. The address of block is being compared to "astring" which returns false.
2. The entire 64 bytes of block are being compared to "astring". Since "astring" is only 8 bytes it returns false.
strcmp is the function you want to use. It will compare everything up to the terminating character.
I will explain why you cannot compare strings like this. It will work if you are using the std::string instead of char[] because string is build with a string compare protocol. A char is really only an 8 bit integer. Declaring char is the exact same as declaring __int8.
Now your char array is an array of 8 bit integers. The compiler recognizes that we don't use 8 bit integers anymore except when holding characters because characters only need 8 bits to convert to a characters based on the ASCII table codes.
Back to the main point, you can't compare arrays. Here is an example:
Here I posted three different ways to hold an array of characters. Now the string put into each array is identical but ... from the computer's point of view they are far from the same. The first one takes up 8008 bits of memory, very large. The second one is a pointer and is pointing to the location of the constant "Hello!" so it is considered 4 bytes in size. The last one is 80 bits long or 10 bytes in length. How can you expect a computer to tell you that a 1001 byte, 10 byte, and 4 byte variable are identical?
When the compiler compares integers, they are set in length so they just check the bits. If all 32 or 64 bits match perfectly, then they are equal. If one is longer then the other, say comparing a 32 bit to a 64 bit, you first need to convert one to the other or visa versa like put (__int64) in front of the 32 bit integer so it will read it as a 64 bit integer.
To figure out if a string is the same as another string, you need to use the function strcmp or manually check each letter to see if it matches.
If you still don't understand because I know my way of explaining it might not be the best way, I can try again if you like in another way. Just let me know.
I think we can explain in this in a more concise manner.
When you compare a variable of type char* or char[] to another variable, you actually compare the address contained in the char* variable to the address of the char[]. You aren't actually comparing strings, just addresses.
Size of the memory pointed to (if any) doesn't have anything to do with it.
you compare the address of block with the address of const character array (string literal) "astring". It is obvious that they have different addresses.
There is no such operator as == to compare arrays. In the statement above array names are converted to addresses of their first elements and these addresses are compared.
To compare character arrays that contain string literals you should use standard function std::strcmp, declared in header file <cstring>
I understand, but ifstream::get() doesn't have an overload for strings so I have to use char[]. Unless anyone knows a way to use it without making an overload function to support strings, I will just stick with strcmp(). Thanks for the explanation everyone.
Wow thanks, not only did that allow me to get rid of the old function but it helped remove a ton of unneeded code for converting char to string for certain functions. :)
Word of caution, don't use getline to input with any other method. getline will work great unless you try to mix an match with other methods. I use getline all the time and only get line because I find it easier to deal with a string then to pick and piece data.
A lot of people pull their hair out not knowing this and trying to make it work. I figure I throw that in there to help save possible later stress.
Currently it is only using getline to extrace values and ignore to skip to the next line. It is also using get to get the first character so it can know what to do, but it moves the position back when it is something that is going to be extracted with getline later. It's working perfect now.