13

I wrote this code in C:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int main()
{
    char string1[20];
    char string2[20];
    strcpy(string1, "Heloooo");
    strcpy(string2, "Helloo");
    printf("%d", strcmp(string1, string2));
    return(0);
}

Should console print value 1 or difference between ASCII values of o and \0 character i.e. 111? On this website, it is written that this should give out put 111, but when I run it on my laptop, it shows 1. Why?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Akhil Raj
  • 457
  • 1
  • 4
  • 14
  • 2
    [strcmp](http://linux.die.net/man/3/strcmp) returns -1 (less than 0), 0 (equal) or 1 (greather than 0). One way to find this out is to google `man strcmp`. NOTES: 1) your "website" is *wrong*. 2) strcmp() expects a C string (a null-terminated char array); *not* an individual "char" value. – paulsm4 Jan 16 '16 at 08:04
  • On which website is written that it should output 111? – tkausl Jan 16 '16 at 08:04
  • 4
    It depends on the implementation. – BLUEPIXY Jan 16 '16 at 08:04
  • 3
    @paulsm your answer is incorrect. it depends on the implemenattion if it gives `-1` it may also give the difference in ascii-values – Peter Miehle Jan 16 '16 at 08:07
  • 3
    @tkausl http://www.tutorialspoint.com/ansi_c/c_strcmp.htm – Akhil Raj Jan 16 '16 at 08:09
  • 1
    @ Peter Miehl3. I've never seen or heard of an implementation that gives anything other than 0, < 0 or > 0. I don't disbelieve you, but... Q: can you cite a link to one? – paulsm4 Jan 16 '16 at 08:11
  • 1
    @paulsm4 in fact most optimized libraries do return the difference between the characters instead of 1 and -1. For example the [Google bionic](https://android.googlesource.com/platform/bionic/+/fe6338d/libc/string/strcmp.c), [glibc and BSD](https://www.systutorials.com/240987/strcmp-and-strncmp-implementation-in-glibc/), [glibc optimized assembly](https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/strcmp.S;h=c5c44d4e27710c0c335f581cf42de37b3eefc9f4;hb=fdfc9260b61d3d72541f18104d24c7bcb0ce5ca2), [musl](http://git.musl-libc.org/cgit/musl/tree/src/string/strcmp.c)... – phuclv May 19 '18 at 14:46
  • 1
    [FreeBSD version](https://github.com/freebsd/freebsd/blob/master/lib/libc/string/strcmp.c) – phuclv May 19 '18 at 14:49

6 Answers6

28

From the cppreference.com documentation

int strcmp( const char *lhs, const char *rhs );

Return value

  • Negative value if lhs appears before rhs in lexicographical order.

  • Zero if lhs and rhs compare equal.

  • Positive value if lhs appears after rhs in lexicographical order.

As you can see it just says negative, zero or positive. You can't count on anything else.

The site you linked isn't incorrect. It tells you that the return value is < 0, == 0 or > 0 and it gives an example and shows it's output. It doesn't tell the output should be 111.

bolov
  • 72,283
  • 15
  • 145
  • 224
  • So, the return value would be -1, 0, 1? or it can be other values? – c-an Jun 10 '20 at 15:21
  • 1
    @c-an any "negative value", "zero", and any "positive value" respectively – bolov Jun 10 '20 at 18:50
  • So, what's the value? How does it determine the value? – c-an Jun 10 '20 at 23:57
  • @c-an it doesn't matter what the value is. The standard don't impose a certain value on purpose. It's up the the implementation. Some just return `-1` `0` and `1`, some might do some optimizations and return a difference. In the comments to the question you have some links to some implementations that return the difference between the first mismatching pair of characters. – bolov Jun 11 '20 at 00:07
6

To quote the man page:

The strcmp() and strncmp() functions return an integer less than, equal to, or greater than zero if s1 (or the first n bytes thereof) is found, respectively, to be less than, to match, or be greater than s2.

In other words, you should never rely on the exact return value of strcmp (other than 0, of course). The only guarantee is that the return value will be negative if the first string is "smaller", positive if the first string is "bigger" or 0 if they are equal. The same inputs may generate different results on different platforms with different implementations of strcmp.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
4

strcmp returns 'a value lesser than 0' if the string1 is alphabetically lesser than string2; zero, if they are equal; and a 'value greater than 0' if string 1 is alphabetically greater than string 2.

DrJessop
  • 462
  • 6
  • 26
Peter Miehle
  • 5,984
  • 2
  • 38
  • 55
4

The output depends on the implementation. A decent implementation of the strcmp function would be:

int strcmp (const char * s1, const char * s2)
{
    for(; *s1 == *s2; ++s1, ++s2)
        if(*s1 == 0)
            return 0;
    return *(unsigned char *)s1 < *(unsigned char *)s2 ? -1 : 1;
}

The above implementation returns -1 if s1 < s2, 1 if s1 > s2 and 0 if s1 = s2.
But usually, there is a faster version which is implemented for actual use:

int strcmp (const char * s1, const char * s2)
{
    for(; *s1 == *s2; ++s1, ++s2)
        if(*s1 == 0)
            return 0;
    return *(const unsigned char *)s1 - *(const unsigned char *)s2;
}

Note that this is faster because it skips the branching which was being done previously. Therefore, we usually have the convention that a negative return value means that s1 is lexicographically smaller than s2, and a positive value means vice-versa.

Aseem Baranwal
  • 304
  • 4
  • 11
  • Historically this may have been a reason, but an optimising compiler will usually be able to avoid an extra branch in the first version. The first version may still be a couple of cycles faster, but this difference will be negligible. Actual `strcmp` in a library will have been optimised much more heavily, see https://stackoverflow.com/questions/44874690/why-is-this-version-of-strcmp-slower – Carsten S Jul 08 '17 at 12:06
2
int strcmp(const char *str1, const char *str2)

will return a value less, equal or greater than 0. If it returns 0 it means that the two strings are equal, if it returns a value minor than 0 it indicates that str1 is less than str2. If it returns a value > 0 it means that str2 is less than str1.

Your return value is 1 because "Heloooo" is one character more then "Helloo". In fact the word Helloo has 6 characters and Heloooo has 7 characters. Exactly one more char.

Claudio Cortese
  • 1,372
  • 2
  • 10
  • 21
-2

Basically, strcmp() can return the following:

  • > 0 if the 2nd string is lesser than the first 1st string.

    char s1, s2;
    strcpy (s1, "helloworld");
    strcpy (s2, "world");
    int check = strcmp (s1, s2);
    
  • 0 if the strings passed are same.

    char s1, s2;
    strcpy (s1, "hello");
    strcpy (s2, "hello");
    int check = strcmp (s1, s2);
    

    In this case, as strings are equal, check will have 0.

  • < 0 if the first string is smaller than the second string.

    char s1, s2;
    strcpy (s1, "hello");
    strcpy (s2, "worldhello");
    int check = strcmp (s1, s2);
    

So in your case, strcmp () will return 1 as the strings are not equal.

Check out this and this tutorials about strcmp ().

phuclv
  • 37,963
  • 15
  • 156
  • 475
Box Box Box Box
  • 5,094
  • 10
  • 49
  • 67