1

I'd like to sort an array of C-style strings but I don't know how to create the comparison function properly.

//the array
char foo[2][4] = { "abc", "cde" };

//the comparison function
bool cmp(char * a, char * b) //<- actually passing parameters causes trouble
{
    for (int i = 0; i < 4; i++)
        if (a[i] < b[i])
            return true;
        else if (a[i] > b[i])
            return false;

    return true;
}

//sorting
std::sort(foo, foo + 2, &cmp);

I'd like this piece of code to be as fast as possible so I don't want to use vectors or structures and pass them as a reference.

Any help will be appreciated.

//edit I apologize for being imprecise. I don't want to re-implement lexicographical sorting because there is an STL function that does it appropriately. The comparison part doesn't really matter. I just wanted to have access to the elements of the strings (in this case 'letters'), do whatever I want to, and influence the std::sort function by returning true or false.

Take a look at the highest rated response: c++ sort with structs I wanted to do the same with an array of C-strings (not structures) - the comparison itself doesn't matter.

10
  • @ShamimHafiz Question is tagged C++. Commented Jun 5, 2013 at 14:34
  • 1
    I don't understand, it will return true if they are equal and if their first character are not equal. Commented Jun 5, 2013 at 14:34
  • How is passing parameters to your cmp function causing trouble? Commented Jun 5, 2013 at 14:34
  • 1
    @jonhopkins std::sort expects a begin and end iterator. Commented Jun 5, 2013 at 14:35
  • 2
    The comparison function is not your only problem. You can't sort foo because its elements are not assignable. Commented Jun 5, 2013 at 14:36

2 Answers 2

3

You can't sort the foo array, because it is a 2-dimensional array. std::sort requires that the elements of the array be assignable. But foo's elements are 1-dimensional arrays, and arrays cannot be assigned.

If you make foo an array of pointers instead, you will be able to sort it:

const char *foo[2] = { "abc", "cde" };

You will also need to make cmp take const char * pointers instead of char *:

bool cmp(const char * a, const char * b)

Other options are to make foo's elements std::array<char, 4>, or a struct containing a char[4] member. Using std::string is the most recommended option unless you have a good reason to avoid it.

Another thing to fix: Your cmp function returns true when passed two equal elements. It should return false instead.

Note that instead of your implementation of cmp, you can take advantage of the strcmp function:

bool cmp(const char * a, const char * b) {
    return std::strcmp(a, b) < 0;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, that absolutely makes sense. I've just tried it and you're right. Thank you very much.
-1
bool cmp(char * a, char * b) //<- actually passing parameters causes trouble
{
int lena = strlen(a);
int lenb = strlen(b) ;   
for (int i = 0; i < lena && i < lenb; i++)
        if (a[i] != b[i])
            return a[i]<b[i];
if ( lena<lenb ) return true;
return false;
}

You basically need to reimplement the strcmp function. Alternatively, you could use it directly, taking care to properly return the boolean values.

3 Comments

Actually, your function will compare only first characters of the strings.
and why one wants to incorrectly reimplement a library funcition?
It's more clear to write return lena < lenb;. You can also pass the arguments as const.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.