I tried to learn the qsort function of the c-library stdlib
. This is provided even in c++
. But i dont understand how to use them for sorting c++
strings. I am not sure of what the parameters should be for the sizeof()
operator and whether my compare_str
code is right. I tried this code:
#include<iostream>
#include<cstdlib>
using namespace std;
#include<string>
int compare_str( const void *a, const void *b){
string obj = (const char*)a;
string obj1 = (const char*)b;
return obj.compare(obj1);
}
int main(){
string obj[4] = {"fine", "ppoq", "tri", "get"};
qsort(obj, 4, sizeof(obj[0].length()), compare_str);
for( int i=0; i<4; i++)
cout<<obj[i]<<endl;
return 0;
}
My output was:
ppoq
tri
get
fine
I am not able to make out the error. Please help.
Works for me:
You cannot and must not use
qsort
on an array ofstd::string
s. The elements must be of trivial type, which strings are not, and thus the behaviour is undefined. From 25.5/4 ("qsort"):The reason is that
qsort
willmemcpy
the array elements around, which is not possible for C++ objects in general (unless they're sufficiently trivial).If you do have a trivial type, you can use this generic qsorter-comparator (but of course this is a terrible idea, and the inlined
std::sort
is always preferable):Use:
T arr[N]; qsort(arr, N, sizeof *arr, qsort_comp<T>);
Don't use this. Use
std::sort
instead.Better be C++ oriented and use std::sort for your array:
AFAIK -
std::sort
uses quick sort.[UPDATE] See comments, std::sort is not always pure quick sort.
[UPDATE2]
If you want to learn qsort - change
std::string
toconst char*
and define function based onstrcmp
. Remember that qsort passes pointers to elements in an array - so dereferenceconst void*
to getconst char*
. See:Your error is in the declaration of the size in
qsort
. What is expected is the size of a member, which is, in your case, a string. So you want to use:However, you need to work with pointer to string, rather than strings themselves. Then, the code should look like:
The problem is that you give qsort an array of C++ strings. In your comparison function, you seem to except C strings, since you cast them to (const char*).
Also, the third parameter of qsort, the size of data, you actually give wrong value. sizeof(obj[0].length()) will result in sizeof(size_t), which is obviously wrong. sizeof(obj[0]) would be more correct, but remember that qsort won't call copy constructor of string, which might lead to problems.
I would suggest not to use qsort with C++ strings.
See answer provided by PiotrNycz for correct solution.
You should use the
std::sort
template function provided by the C++ standard library (in the<algorithm>
header file). By default,std::sort
uses the less than comparison operator to order elements (std::string
already implementsoperator<
). If you need to specify an ordering condition (for example, case insensitive string compare),std::sort
allows you to specify an ordering function object.Example: