tags:

views:

96

answers:

3

according to this site

http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/

i have done following program which sorts strings

#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char list[5][4]={"dat","mai","lik","mar","ana"};
int main(int argc, char *argv[])
{
    int x;
    puts("sortirebamde:");
     for (x=0;x>sizeof(list)/sizeof(char);x++)
     printf("%s\n",list[x]);
      qsort(&list,(sizeof(list)/sizeof(char)),sizeof(list[0]),strcmp);
    system("PAUSE");
    return EXIT_SUCCESS;
}

Here is the error I get

13 C:\Documents and Settings\LIBRARY\Desktop\string_sortireba.cpp invalid conversion from `int (*)(const char*, const char*)' to `int (*)(const void*, const void*)' 
13 C:\Documents and Settings\LIBRARY\Desktop\string_sortireba.cpp   initializing argument 4 of `void qsort(void*, size_t, size_t, int (*)(const void*, const void*))' 

Please help

A: 

The fourth argument of qsort takes 2 void* pointers as args.So you need to define a compare function for yours. refer to this link for more details.

Raghuram
+5  A: 

You can't pass strcmp directly to qsort as its comparison function because qsort expects to pass pointers to void where strcmp expects pointers to const char. Given the required similarity between pointers to void and pointers to char, you could probably do it with a cast, but the cleaner way would be to write a function that takes the right types:

int cmpstr(void const *a, void const *b) { 
    char const *aa = (char const *)a;
    char const *bb = (char const *)b;

    return strcmp(aa, bb);
}

Note, however, that in C++ you'd normally want to use std::sort instead of qsort, and probably use std::string instead of char *, which case the sorting gets a lot simpler (and generally faster as well).

Jerry Coffin
A: 

Beyond why qsort fails, don't use it in C++.

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

char const* const raw_data[5] = {"dat", "mai", "lik", "mar", "ana"};

std::vector<std::string> data (raw_data, raw_data + 5);
// would rarely be a global

// see below for code that needs to go here

int main() {
  using namespace std;
  cout << "before: " << data << "\n";
  sort(data.begin(), data.end());
  cout << "after: " << data << "\n";
  return 0;
}

Boost has stream inserter overloads to output a vector directly, but here's one simple version. This goes into a header, rather than being copied and pasted continually:

template<class Stream, class Iter, class Ch>
void write_sequence(Stream& s, Iter begin, Iter end, Ch const* initial, Ch const* sep, Ch const* final) {
  if (initial) {
    s << initial;
  }
  if (begin != end) {
    s << *begin;
    ++begin;
    for (; begin != end; ++begin) {
      if (sep) {
        s << sep;
      }
      s << *begin;
    }
  }
  if (final) {
    s << final;
  }
}

template<class T, class A>
std::ostream& operator<<(std::ostream& s, std::vector<T,A> const& value) {
  write_sequence(s, value.begin(), value.end(), "[", ", ", "]");
  return s;
}
Roger Pate