如何在c中使用qsort比较C++字符串?

Niv*_*tha 3 c++ string qsort

我试着学习c-library的qsort功能stdlib.这甚至提供c++.但我不明白如何使用它们来排序c++字符串.我不确定sizeof()操作员的参数应该是什么,以及我的compare_str代码是否正确.我试过这段代码:

    #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;
    }
Run Code Online (Sandbox Code Playgroud)

我的输出是:

ppoq
tri
get
fine
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚错误.请帮忙.

Ker*_* SB 11

你不能也不能qsort在一个std::strings 数组上使用.元素必须是普通类型,哪些字符串不是,因此行为是不确定的.从25.5/4("qsort"):

除非指向的数组中的对象base具有普通类型,否则行为是未定义的.

其原因是,qsortmemcpy数组元素周围,这是不可能的,一般的C++对象(除非它们是充分地微不足道).


如果你有一个普通的类型,你可以使用这个通用的qsorter-comparator(但当然这是一个糟糕的想法,并且内联std::sort总是更可取):

template <typename T>
int qsort_comp(void const * pa, void const * pb)
{
    static_assert<std::is_trivial<T>::value, "Can only use qsort with trivial type!");

    T const & a = *static_cast<T const *>(pa);
    T const & b = *static_cast<T const *>(pb);

    if (a < b)  { return -1; }
    if (b < a)  { return +1; }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用: T arr[N]; qsort(arr, N, sizeof *arr, qsort_comp<T>);


不要使用它.请std::sort改用.


Pio*_*ycz 8

最好是面向C++并为您的数组使用std :: sort:

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

int main() {

   std::string obj[4] = {"fine", "ppoq", "tri", "get"};
   std::sort(obj, obj + 4);
   std::copy(obj, obj + 4, std::ostream_iterator<std::string>(std::cout, "\n"));
}
Run Code Online (Sandbox Code Playgroud)

AFAIK - std::sort使用快速排序.

[更新]看到评论,std :: sort并不总是纯粹的快速排序.

[UPDATE2]

如果您想了解快速排序-变化std::stringconst char*和定义功能基础上strcmp.请记住,qsort将指针传递给数组中的元素 - 因此取消引用const void*get const char*.看到:

#include <stdlib.h>
#include <string.h>

int compare_cstr(const void* c1, const void* c2) 
{ 
   return strcmp(*(const char**)(c1), *(const char**)(c2)); 
}

int main() {

   const char* obj[4] = {"fine", "ppoq", "tri", "get"};
   qsort(obj, 4, sizeof(obj[0]), compare_cstr);
   std::copy(obj, obj + 4, std::ostream_iterator<const char*>(std::cout, "\n"));
}
Run Code Online (Sandbox Code Playgroud)