tags:

views:

157

answers:

9

i try to compare between 2 char* identical strings,but one of them contains a null terminator at the end. i've been looking through the internet and understood that it's not recommendable to remove the null terminator char cause it will make the string unstable. what other methods can i use?

the comparing function:

int StringCompare(const char* str1, const char* str2)  
{
    int size1 = strlen(str1), size2 = strlen(str2), min = 0, index =0;  
    bool bigger1 = true;  
    if(size1>size2)  
        min=size2;  
    else  
        min=size1;  
    for(index=0;index<min;index++)  
    {  
        if(str1[index]>str2[index])  
            return 1;  
        if(str1[index]<str2[index])  
            return (-1);  
    }  
    if(size1==size2)  
        return 0;  
    if(min==size1)  
        return (-1);  
    else  
        return 1;  
}    

thanks!

+4  A: 

You are using strlen which requires a null terminator at the end of the string. If one of the strings you pass doesn't have a terminator, you are guaranteed to fail.

Mark Ransom
what other function can tell me the size of char*?
shiran bar
@shiran bar, There's the `sizeof` operator, but that's probably not what you want. What are you trying to accomplish? If you can clarify your goals, we can better help you understand what you need to do.
strager
@shiran bar, the classic `char *` string inherited from C ends with a null by definition. You can use `std::string` instead which contains the length as a separate attribute, or you can pass a length into the function along with the strings.
Mark Ransom
i want to compare the actual content of the strings, without considering the null terminator at the end of one of them. is there a function that can do that or returns the size of a string without counting the null terminator?
shiran bar
strlen doesn't count the NUL at the end, and strn?cmp doesn't consider the NUL.
Matt Kane
we tried working with string instead but the same problem occurs, the size is still different.
shiran bar
@Matt Kane, `strncmp` does consider the NUL.
strager
@shiran bar, the problem may not be what you think it is. See http://stackoverflow.com/q/3765454/5987
Mark Ransom
we tried using strncmp it doesn't work as well, or maybe we're doing it wrong: int StringCompare(const char* str1, const char* str2) { int size1 = strlen(str1), size2 = strlen(str2), max = 0, index =0; if(size1<size2) max=size2; else max=size1; return (strncmp(str1,str2,max)); }
shiran bar
If you want to compare two arrays of characters (perhaps char*'s) without regard to contained nuls, you want `memcmp`, which requires the length of the arrays as a third parameter. I hope you know how long they are.
TokenMacGuy
+3  A: 

I would hope that both your char* strings have null terminators at the end! The null terminator is what enables functions like strlen to determine the length, and know when the string ends.

Anthony Williams
+4  A: 

You're calling strlen on both, so they better both have NULs (not NULL) at the end. Once you get to one of the NUL, you need to stop comparing, because the string is done! That's it! Any subsequent data does not belong to that string.

Matt Kane
+2  A: 

Your code can't possibly work unless both str1 and str2 have null terminators. Otherwise, how do you (or strlen) know how long they are?

If the real question is "How can I work with strings that contain embedded NUL characters?", you should use a vector<char> or similar. You're no longer talking about strings, because by definition strings are NUL-terminated.

RichieHindle
+3  A: 

Please read this posting about C Strings and understand it. ALL c strings requires a nul terminator to signify to the C runtime, that the end of string has been reached. The nul terminator is \0. Notice the distinction between the usage of nul and null, in order to clear any potential confusions - when dealing with strings, its nul, with pointers its NULL!

tommieb75
Because you are simply referring to another post (even if it is your own), I would recommend you make this a CW answer.
strager
+5  A: 

Use std::string, that's what it's for. Failing common sense, use strcmp().

DeadMG
+1 well duh ...
pm100
+2  A: 

If you're trying to compare 2 strings and you cannot be sure they will both be null terminated, you're method signature needs to take the size of the passed strings as arguments, otherwise strlen will tell you how many bytes there are from the char* pointer to the first memory location of 0.

Paul Whitehurst
+3  A: 

If you know which of the two strings has null terminator, you can call strlen() on it and use that as the length of both strings. But that's a terrible hack - you're not really comparing anything.

Suppose you have two strings:

"abc\0"
"abcdef\0"

Is string 2 null-terminated? Or is "def\0" part of it just random garbage?

The only way to be sure is to null-terminate all strings.

Arkadiy
+3  A: 

If only one of the strings is null terminated, you should modify your for loop to end when the null is reached for either string, and omit the strlen() call.

for(index=0;;index++)  
{  
    if(!str1[index]) {
        if(!str2[index]) 
            return 0; // strings are equal in length
        return -1; // str1 < str2 since str2 is longer
    }
    if(!str2[index]) 
        return 1;  // str1 > str2 since str1 is longer     

    if(str1[index]>str2[index])  
        return 1;  
    if(str1[index]<str2[index])  
        return (-1);  
}  

Note that this has the same effect as Matteo Italia's answer.

levis501