简体   繁体   中英

comparing strings with “<” or “>” operators (C)

I try to understand if there is a defined behavior to the following operation in C:

char *str1 = "some string";
char *str2 = "another string";
if (*str1 > *str2)
    //do something...
else
    //do something else...

(As mentioned in the title, I mean to the "comparison" between the strings using ">" operator)

Obviously if I would try:

str1 > str2

(without the * operator)

it would calculate the results according to the pointer (ie the string's address)(right..?). I searched answers for it but haven't found any, and I didn't succeed to understand it by playing with the code neither. thanks.

With the indirection operator * you are actually comparing the values of the characters the pointers point to at the moment of the dereference.

So in your code, it's comparing 's' to 'a' as follows 's' > 'a' which is true.

The values have char type and hence it's well defined to use the < , > == , >= , <= , != operators.

Be careful when declaring a pointer to a string literal, use the const qualifier to prevent accidentally modifying it because that would be undefined.

In C, there is no "string type", just the convention that a char * pointing to a sequence of char s terminated by a null byte is called "string".

To compare string contents, use strcmp( const char *lhs, const char *rhs ) .

*str1 > *str2 does not compare the strings, it compares their first characters.

str1 > str2 does not compare the strings either, and while it does "compare their addresses" on many platforms, strictly speaking it is undefined behaviour .

From the C standard, 6.5.8 Relational operators (which includes > ), paragraph 5, emphasis mine:

When two pointers are compared, the result depends on the relative locations in the address space of the objects pointed to. If two pointers to object or incomplete types both point to the same object , or both point one past the last element of the same array object , they compare equal.

If the objects pointed to are members of the same aggregate object , pointers to structure members declared later compare greater than pointers to members declared earlier in the structure, and pointers to array elements with larger subscript values compare greater than pointers to elements of the same array with lower subscript values.

All pointers to members of the same union object compare equal. If the expression P points to an element of an array object and the expression Q points to the last element of the same array object , the pointer expression Q+1 compares greater than P.

In all other cases, the behavior is undefined.

Without the * operator, you are actually comparing the addresses of str1 and str2 , which causes undefined behavior, because they are not pointers to a same aggregate object or union or object.

With a * operator, however, you dereference their addresses, so what you compare becomes the values of the two string literals' first elements. In this code, there are no undefined behaviors.

"some string" and "another string" are string literals. They are have types of character arrays correspondingly char[12] and char[15]

In this statements

char *str1 = "some string";
char *str2 = "another string";

pointers str1 and str2 are initialized by the addresses of the first characters of the string literals.

What you want is to compare these string literals that is two strings stored in character arrays.

If you write

if (*str1 > *str2)
    //do something...

then *str1 and *str2 are just first characters of the string literals. That is the condition in the if statement compares two characters. It is equivalent to the following statement

if (str1[0] > str2[0])
    //do something...

Arrays do not have relational operators like <, <=, >, or >=. If you want to compare two arrays you have to compare their elements separatly.

However for character arrays that contain strings (sequence of characters terminated by zero) there are standard functions like strcmp , strncmp , memcmp declared in header <string.h>

For example (The C Standard, 7.23.4.2 The strcmp function)

3 The strcmp function returns an integer greater than, equal to, or less than zero, accordingly as the string pointed to by s1 is greater than, equal to, or less than the string pointed to by s2.

So if you want to determine whether the first string literal is greater than the second string literal you should write

if ( strcmp( str1, str2 ) > 0 )
    //do something...

If you want to determine whether the first string literal is greater than or equal to the second string literal you should write

if ( strcmp( str1, str2 ) >= 0 )
    //do something...

If you want to determine whether the first string literal is less than the second string literal you should write

if ( strcmp( str1, str2 ) < 0 )
    //do something...

If you want to determine whether the first string literal is less than or equal to the second string literal you should write

if ( strcmp( str1, str2 ) <= 0 )
    //do something...

You can not compare two strings like two integers. In order to do that you can use strcmp(char *firstStr, char *secondStr) . The return value of the strcmp is an integer.

char *str1 = "some string";
char *str2 = "another string";
int difference;

difference = strcmp(str1,str2);

if(difference < 0)
{
  printf("str1 is less than str2");
}
else if(difference > 0) 
{
   printf("str2 is less than str1");
}
else if (!difference)  //(difference == 0)
{
   printf("str1 is equal to str2");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM