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.

Community
  • 1
  • 1
w0jt
  • 55
  • 5
  • @ShamimHafiz Question is tagged C++. –  Jun 05 '13 at 14:34
  • 1
    I don't understand, it will return true if they are equal and if their first character are not equal. – Djon Jun 05 '13 at 14:34
  • How is passing parameters to your `cmp` function causing trouble? – jonhopkins Jun 05 '13 at 14:34
  • 1
    @jonhopkins `std::sort` expects a begin and end iterator. –  Jun 05 '13 at 14:35
  • Ah, okay. Nevermind on that part then. – jonhopkins Jun 05 '13 at 14:36
  • 2
    The comparison function is not your only problem. You can't sort `foo` because its elements are not assignable. – interjay Jun 05 '13 at 14:36
  • @Djon, Not first, function will check all(`4`) characters in the given strings. If they are equal, function will return `true`. So, this function is equal with `operator<=` for `std::string`. – awesoon Jun 05 '13 at 14:46
  • @Pedrom: yes I tried it and it fails horribly, interjay is correct, I'm removing my answer. – stefaanv Jun 05 '13 at 14:55
  • "Take a look at the highest rated response: c++ sort with structs" please note that the answer assumes that you would use a stl container and not an array... this is because stl::sort needs iterators as parameters – Pedrom Jun 05 '13 at 15:00
  • So many deleted answers (mine included), while sorting a vector of strings is completely straightforward... – stefaanv Jun 05 '13 at 15:57

2 Answers2

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;
}
interjay
  • 107,303
  • 21
  • 270
  • 254
  • Yes, that absolutely makes sense. I've just tried it and you're right. Thank you very much. – w0jt Jun 05 '13 at 15:21
-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.

Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176