2010-03-04 5 views
0

J'essaie de trier un tampon complet d'enregistrements de longueur variable par ordre alphabétique en C++. J'ai précédemment demandé comment implémenter ceci, et on m'a dit de trier un tableau de pointeurs vers les enregistrements. J'ai mis en place un tableau de pointeurs, mais j'ai réalisé que chaque pointeur pointe vers le début d'un enregistrement, mais il n'y a aucun moyen de savoir quand l'enregistrement s'arrête. Lorsque j'essaie d'imprimer l'enregistrement pointé par chaque pointeur dans le tableau, par conséquent, pour chaque pointeur, j'obtiens le tampon entier de tous les enregistrements, en commençant par celui pointé vers. (Par exemple, si le tampon contient "Helloworld", et qu'il y a un pointeur sur chaque lettre, l'impression du tableau de pointeurs produirait "Helloworldelloworldlloworldworldworldorldrldldd".) Evidemment, ce n'est pas ce que je veux; De plus, le qsort ne semble pas non plus fonctionner sur le tableau des pointeurs. Lorsque je débogue, les espaces mémoire pointés par les pointeurs semblent contenir des caractères très étranges qui ne font absolument pas partie du jeu de caractères ASCII et qui n'ont pas été inclus dans mon fichier d'entrée. Je suis très confus. Voici mon code. comment puis-je faire cela sans obtenir les résultats bizarres que je reçois maintenant? Merci beaucoup, bsg.C++ qsort tableau de pointeurs ne pas trier

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

Regardez plus comme C que C++ pour moi ... – ALOToverflow

+2

Votre fonction de comparateur est * très * fausse - pensez à ce que vous essayez réellement de faire ici. –

+1

Pourquoi utilisez-vous _tmain, mais en utilisant directement le caractère dans le reste du code? – jmucchiello

Répondre

1

Je suppose que le problème est dans votre fonction de comparaison (qui ne compile pas tel que publié). qsort donne un pointeur sur l'élément de tableau à la fonction de comparateur. Dans votre cas, il s'agit d'un pointeur sur, le char* étant stocké dans le tableau.

La page de manuel pour qsort donne cet exemple:

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

Cette question se résume à 'comment savez-vous la longueur de votre dossier de longueur variable.' Il doit y avoir un moyen de le savoir, soit à partir de l'enregistrement lui-même, ou à partir d'autres données. L'une des façons consiste à utiliser des paires pointeur/longueur pour désigner les enregistrements - un pointeur vers le début de l'enregistrement et une longueur (int ou size_t) que vous stockez dans une structure. Avec C++ vous pouvez utiliser std :: pair, ou avec C define a litte struct. Vous pouvez ensuite utiliser qsort sur un tableau de ceux-ci.

Dans votre cas, vous pouvez indiquer la longueur en recherchant un caractère (10), car vous les utilisez toujours pour terminer vos chaînes. Vous avez besoin d'une comparaison personnalisée (strcmp ne fonctionnera pas - il attend des terminaisons NUL) qui en est conscient.

Questions connexes