2015-01-31 264 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