2015-01-31 147 views
-3

我试图从一个包含另一个int变量的类中按字母顺序排序对象数组,但是我无法正常工作qsort函数。 这是我的代码:在C++中对对象数组排序

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

int cmp (char **str1 , char **str2) 
{ 
    return strcmp(*str1,*str2); 
} 

class myclass 
{ 
int id; 
char text[50]; 
public: 
    void add(char a[], int i) { strcpy(text,a); id=i; } 
    void show(void) { std::cout<<text<<std::endl; } 
}; 


int main (void) 
{ 
    myclass * myobject[4]; 
    myobject[0] = new myclass; 
    myobject[1] = new myclass; 
    myobject[2] = new myclass; 
    myobject[3] = new myclass; 
    myobject[0]->add("zoom",1); 
    myobject[1]->add("zoo",2); 
    myobject[2]->add("animal",3); 
    myobject[3]->add("bull",4); 

    qsort (myobject,4,sizeof(char *), (int (*)(const void *, const void *)) cmp); 

    for (int i=0; i < 4; i++) 
    myobject[i]->show(); 

    return 0; 
} 
+0

而'qsort()'实际上是? – 2015-01-31 18:11:36

+2

@πάνταῥεῖ一个标准的C/C++库函数。 – Barmar 2015-01-31 18:12:15

+4

为什么不使用'std'容器而不是数组。然后你可以使用'std :: sort',或者使用一个容器来保持数据一直排序。 – Barmar 2015-01-31 18:13:12

回答

0

首先,你的比较函数需要能够访问私有成员文本MyClass的

你既可以使文本公共或类定义添加

friend int cmp (const void *, const void*); 

二,你的比较功能是错误的。它需要指向要排序的数组成员。你应该把它写这样的:

int cmp (const void *ptr1 , const void *ptr2) 
{ 
    myclass *m1 = *(myclass**)ptr1; 
    myclass *m2 = *(myclass**)ptr2; 

    return strcmp(m1->text, m2->text); 
} 
+0

这只是我需要做的一切工作。感谢您的朋友功能代码提示,我忘了它! – DvD23 2015-02-01 16:08:24

0

您的比较函数是错误的。它接收到指向每个数组元素的指针,这是指向myclass而不是text的指针。当调用qsort时,您也不应该投射函数指针,您应该在比较函数中强制转换参数。

int cmp (void *a, void *b) { 
    myclass **c1 = (myclass **)a; 
    myclass **c2 = (myclass **)b; 
    return strcmp((*c1)->text, (*c2)->text); 
} 
+0

这个答案解决了这个问题,非常感谢Barmar! – DvD23 2015-01-31 18:26:44

+0

@NicholasM我在评论中提到过。 – Barmar 2015-01-31 18:49:28

+0

你是对的;我会删除我的评论。 – NicholasM 2015-01-31 18:50:30

1

现在,你的代码看起来像C代码变形版本,只有足够的C++“洒”在保持它与C编译器的工作。至少国际海事组织,这给了两个世界上最糟糕的 - 它消除了C的大多数最好的功能,以及C++的最佳功能。如果你打算写C++,写C++,不扭曲C.

创建和排序在C对象的集合++,你应该写代码更是这样的:

#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 

class myclass 
{ 
    int id; 
    std::string text; 
public: 
    myclass(std::string const &a, int i) : id(i), text(a) {} 

    bool operator<(myclass const &other) { 
     return text < other.text; 
    } 

    friend std::ostream &operator << (std::ostream &os, myclass const &m) { 
     return std::cout << m.text << "\n"; 
    } 
}; 


int main() 
{ 
    std::vector<myclass> myobjects{ 
     { "zoom", 1 }, 
     { "zoo", 2 }, 
     { "animal", 3 }, 
     { "bull", 4 } 
    }; 

    std::sort(myobjects.begin(), myobjects.end()); 

    for (auto const &o : myobjects) 
     std::cout << o; 
} 

至少在我看来,这是比较简单和容易理解的。它不会泄漏内存。如果(例如)我们向项目集合添加了另一个项目,我们不必重写其他代码来适应这些项目。

可能比上述任何一个更重要的是,至少对我来说这会导致更快,更容易,更无bug的开发。举个例子,上面的代码第一次编译时没有bug(正常工作)。除了修正几个明显的拼写错误(例如,我错误地输入了operator作为opertor),它编译和运行的方式与我最初输入的内容完全一样。作为一个小小的奖励,它可能比类似C的版本运行得更快。只有4件商品,速度差别不会很明显,但如果您有(例如)成千上万件商品,则std::sort几乎肯定会比qsort快很多(相当常见的快两到三倍)。

+0

是的,你是真的,但我必须在使用过时库的Dev-C++中编译我的文件,这就是我试图使用qsort的原因。感谢您的代码,我将为未来的程序保留! – DvD23 2015-02-01 16:05:32

+0

@ DvD23:如果你使用的编译器太老了,它真的缺少'std :: sort',唯一合理的反应是更新编译器。任何在过去的20年(或其他)发布的东西都应该有'std :: sort'。 – 2015-02-01 18:13:54