Eric
Eric

Reputation: 24890

c - make string compare function more brief

I wrote a function to compare 2 strings, return int as compare result, and pass an additional int pointer as param to retrieve the max match lengh.

// compare 2 strings

#include <stdio.h>

/**
 * compare 2 string,
 * 
 * @param sa
 *  string 1
 * @param sb
 *  string 2
 * @param len
 *  a int pointer pass from outside to store match length,
 * 
 * return
 *  0 if equlas, <0 if (a < b), >0 if (a > b),
 */
static int strCompare (char *sa, char *sb, int *len) {
    for((*len)=0; *sa==*sb; sa++,sb++, (*len)++) {
        // handle equals case, prevent ++ for \0,
        if(!*sa)
            break;
        // printf("%c,%c\n", *sa, *sb);
    }
    return *sa - *sb;
}

int main(int argc, char *argv[]) {
    if(argc < 3) {
        printf("need 2 arguments.\n");
        return 0;
    }
    int matchLen = 0;
    int result = strCompare(argv[1], argv[2], &matchLen);
    printf("compare:\n\t%s\n\t%s\nresult: %d\nmatch length: %d\n", argv[1], argv[2],
        result, matchLen);
    return 0;
}

Question:

I want the loop be more brief, e.g. avoid the if inside for, but didn't found out by myself, can anyone help to write a brief version with the same function interface.

(Please don't use libc function, I do this to improve my code style ;)

Upvotes: 2

Views: 143

Answers (3)

Morpfh
Morpfh

Reputation: 4093

Perhaps something like:

static int str_compare(const char *a, const char *b, size_t *len) {
    const char *p = a;

    for ( ; *p && *p == *b; ++p, ++b)
        ;

    *len = p - a;
    return *p - *b;
}

As Duplicator has mentioned use const for input strings.

Also size_t is widely used for sizes and counts, so likely better.

Alternative by tracking length:

static int str_compare(const char *a, const char *b, size_t *n) {
    for (*n = 0; a[*n] && a[*n] == b[*n]; ++*n)
        ;

    return a[*n] - b[*n];
}

Does not look too good with all the indirection on n, but still.


As a side note; you should return 1 (or something other then 0) on error (in main).

Upvotes: 1

Deduplicator
Deduplicator

Reputation: 45654

You might want to avoid the repeated reads and writes through the pointer while you are at it, and go for const-correctness:

static int strCompare (const char *sa, const char *sb, int *len) {
    int tlen = 0;
    while(*sa && *sa == *sb)
        ++tlen, ++sa, ++sb;
    *len = tlen;
    return *sa - *sb;
}

Or maybe better with restrict:

static int strCompare (const char *sa, const char *sb, int * restrict len) {
    *len = 0;
    while(*sa && *sa == *sb)
        ++*len, ++sa, ++sb;
    return *sa - *sb;
}

BTW: The only thing making the code more efficient in the first case is avoiding the repeated writes through len.
In the second, it's using restrict and thus reducing aliasing (which will also remove all but the last write).

Also, consider whether size_t would not be a better type for the length.

Upvotes: 3

Karthikeyan.R.S
Karthikeyan.R.S

Reputation: 4041

In your code if condition is needed. Because you are checking the pointer. If you accessing the pointer that is not allocate that will give you a segmentation fault. So avoid this you have to do the if condition. Or else you can made that in the for loop.

for((*len)=0; *sa==*sb && *sa!='\0' ; sa++,sb++, (*len)++);

So avoiding the segmentation fault you need the another condition for checking.

Upvotes: 1

Related Questions