Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function returning 101 and -101 instead of 1 and -1

So my professor gave us the assignment to code a function that works exactly like strcmp() but without using any library functions. I came up with the following code but instead of returning 1 or -1 when one of the strings is longer than the other one, the output shows 101 and -101.

#include <stdio.h>

int string_compare(char v[], char w[]) {
    int sizeV = sizeof(v) / sizeof(v[0]);
    int sizeW = sizeof(w) / sizeof(w[0]);

    if(sizeV == sizeW) {
        int i;
        int x = 0;

        for(i = 0; i < sizeV; i++) {
            if(v[i] != w[i]) {
                x = v[i] - w[i];
                break;
            }
        }

        return x;

    } else return (sizeV > sizeW) ? 1 : -1;
}

int main(void) {
    
    printf("'abcd', 'abcD': %d", string_compare("abcd", "abcD"));
    printf("\n'abcd', 'abcde': %d", string_compare("abcd", "abcde"));
    printf("\n'abcde', 'abcd': %d", string_compare("abcde", "abcd"));
    printf("\n'', '': %d", string_compare("", ""));
    printf("\n'abcd', 'abcd': %d", string_compare("abcd", "abcd"));

    return 0;
}

This is the output i get:

'abcd', 'abcD': 32
'abcd', 'abcde': -101
'abcde', 'abcd': 101
'', '': 0
'abcd', 'abcd': 0
like image 352
Nebelmonster Avatar asked Aug 31 '25 03:08

Nebelmonster


1 Answers

There are multiple problems:

  • sizeof is inappropriate to compute the length of arrays passed as function arguments: the function just receives a pointer, despite the array-like syntax. Test for the null terminator instead.

  • the return value can be any integer value, what matters is whether it is negative, zero or positive.

Here is a modified version:

#include <limits.h>
#include <stdio.h>

int string_compare(const char *v, const char *w) {
    const unsigned char *p = (const unsigned char *)v;
    const unsigned char *q = (const unsigned char *)w;
    while (*p && *p == *q) {
        p++;
        q++;
    }
#if UCHAR_MAX < INT_MAX
    return *p - *q;  // faster for most architectures
#else
    return (*p > *q) - (*p < *q);  // correct for other cases
#endif
}

int signof(int n) {
    return n == 0 ? 0 : n < 0 ? -1 : 1;
}

void test(const char *s1, const char *s2) {
    printf("'%s', '%s': %d\n", s1, s2, signof(string_compare(s1, s2)));
}

int main(void) {
    test("abcd", "abcD");
    test("abcd", "abcde");
    test("abcde", "abcd");
    test("", "");
    test("abcd", "abcd");
    return 0;
}
like image 182
chqrlie Avatar answered Sep 02 '25 16:09

chqrlie