2010-03-04 183 views
0

我想在C++中按字母順序排列一個充滿可變長度記錄的緩衝區。我以前問過如何實現這一點,並被告知要對記錄的指針數組進行排序。我設置了一個指針數組,但是意識到每個指針都指向記錄的開始,但是無法知道記錄何時停止。當我嘗試打印數組中每個指針所指向的記錄時,因此,對於每個指針,我從所指向的那個開始獲取所有記錄的整個緩衝區。 (例如,如果緩衝區包含「Helloworld」,並且每個字母都有一個指針,則打印指針數組將產生「Helloworldelloworldlloworldloworldoworldworldorldrldldd」。)顯然,這不是我想要的;另外,qsort似乎也沒有在指針數組上工作。當我調試時,指針指向的內存空間似乎包含非常奇怪的字符,絕對不是ascii字符集的一部分,並且未包含在我的輸入文件中。我很困擾。以下是我的代碼;我怎麼能做到這一點,而不會得到我現在得到的奇怪結果?非常感謝你,bsg。C++ qsort不排序的指針數組

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    //allocate memory for the buffer 
    buff = (unsigned char *) malloc(2048); 
    realbuff = (unsigned char *) malloc(NUM_RECORDS * RECORD_SIZE); 

fp = fopen("postings0.txt", "r"); 
     if(fp) 
     { 
      fread(buff, 1, 2048, fp); 
      /*for(int i=0; i <30; i++) 
       cout << buff[i] <<endl;*/ 

      int y=0; 

//create a pointer to an array of unsigned char pointers 
    unsigned char *pointerarray[NUM_RECORDS]; 
    //point the first pointer in the pointer array to the first record in the buffer 
      pointerarray[0] = &buff[0]; 
      int recordcounter = 1; 



     //iterate through each character in the buffer; 
    //if the character is a line feed (denoting a new record), 
// point the next pointer in the pointer array to the next 
//character in the buffer (that is, the start of the next record) 
       for(int i=0;i <2048; i++) 
      { 
       if(buff[i] == char(10)) 
       { 
        pointerarray[recordcounter] = &buff[i+1]; 
        recordcounter++; 
       } 


    } 

//the actual qsort (NUM_RECORDS is a constant declared above; omitted here) 
    qsort(pointerarray, NUM_RECORDS, sizeof(char*), comparator); 

     } 

     else 
      cout << "sorry"; 

     cout << sizeof(pointerarray)/sizeof(char*); 
    for(int k=0; k < sizeof(pointerarray)/sizeof(char*);k++) 
    { 
     cout << pointerarray[k]; 
    } 

int comparator(const void * elem1, const void * elem2) 
{ 

    //iterate through the length of the first string 
    while(*firstString != char(10)) 
    { 
     return(strcmp(firstString, secondString)); 

       firstString++; 
     secondString++; 

     /  
    } 
return 0; 
    } 
+5

看起來更像C而不是C++ ...... – ALOToverflow

+2

你的比較函數*非常錯誤 - 想想你實際上在這裏做什麼。 –

+1

爲什麼你使用_tmain,但直接在代碼的其餘部分使用char? – jmucchiello

回答

1

我猜這個問題是在你的比較函數(它不能像發佈那樣編譯)。 qsort給出了一個指向比較函數的數組元素的指針。在你的情況下,這將是一個指針char*存儲在數組中。

qsort手冊頁給出了這樣的例子:

static int 
cmpstringp(const void *p1, const void *p2) 
{ 
    /* The actual arguments to this function are "pointers to 
     pointers to char", but strcmp(3) arguments are "pointers 
     to char", hence the following cast plus dereference */ 

    return strcmp(* (char * const *) p1, * (char * const *) p2); 
} 

int 
main(int argc, char *argv[]) 
{ 
    int j; 

    assert(argc > 1); 

    qsort(&argv[1], argc - 1, sizeof(char *), cmpstringp); 

    for (j = 1; j < argc; j++) 
     puts(argv[j]); 
    exit(EXIT_SUCCESS); 
} 
1

這個問題基本上可以歸結爲「你怎麼知道你的變長記錄的長度。」需要通過記錄本身或其他一些數據來說明某種方式。

一種方法是使用指針/長度對來引用記錄 - 指向記錄開頭的指針和一起存儲在結構中的長度(int或size_t)。用C++,你可以使用std :: pair,或者用C定義一個litte結構體。然後你可以在這些數組上使用qsort。

在你的情況下,你可以通過查找char(10)來判斷長度,因爲你總是用它來終止你的字符串。你需要一個自定義的比較(strcmp不會工作 - 它期望NUL終止符)知道這一點。