Question

Je travaille sur un devoir à la maison que je suis obligé d'utiliser des tableaux de chaînes au lieu ombles et qsort / bsearch. Dans mon appel à BSEARCH ci-dessous, I sais Je passe la mauvaise taille d'entrée, mais je ne suis pas sûr de savoir comment obtenir la taille réelle, et ma fonction compareEntries est donc de ne pas trouver les bons objets .

Quelqu'un peut me aider à comprendre ce que je suis absent?

#include  <iostream>

using  namespace  std;


typedef Entry*  EntryPtr;
class  Dictionary
{
    public  :
        Dictionary( const char  *filename );
        ~Dictionary();
        const char  *lookupDefinition( const char  *word );

    private  :
        int m_numEntries;
        EntryPtr *m_entries;
        static int compareEntries(const void *leftSide, const void *rightSide);
};

int Dictionary::compareEntries(const void *leftSide, const void *rightSide)
{
    EntryPtr lside = (EntryPtr) leftSide;
    EntryPtr rside = (EntryPtr) rightSide;

    return strcmp(lside->Word, rside->Word);
}

const char *Dictionary::lookupDefinition(const char *word)
{
    if (m_numEntries == 0)
        return 0;

    EntryPtr result = (EntryPtr) bsearch(word, m_entries, 
        m_numEntries, sizeof(m_entries[0]), Dictionary::compareEntries);

    return result->Definition;
}

class Entry
{
        public:
                Entry(const char *line);
                char *Word;
                char *Definition;
};

int  main()
{
    Dictionary  dict( "C:\\path\\file.txt" );
    dict.lookupDefinition("chair");
    return  0;
}
Était-ce utile?

La solution

Pourquoi ne sizeof(Entry) pas de travail?

a changé à nouveau - Je pense que la taille devrait être la taille du pointeur ....

EntryPtr tmp = new Entry("");
tmp->Word = word;

EntryPtr result = (EntryPtr) bsearch(tmp, m_entries, 
        m_numEntries, sizeof(EntryPtr), Dictionary::compareEntries);

Autres conseils

Le problème est que la fonction de comparateur utilisé en bsearch attend word être de type Entry* (ou m_entries être de type char**).

Vous ne savez que bsearch requiert une entrée triée, à droite?

sizeof(m_entries[0]) semble parfaitement bien pour moi.

Edit: Maintenant, je vois le problème. Votre classe Dictionary contient un tableau de pointeurs. Le problème est dans la fonction compareEntries, où vous CAST passé des pointeurs vers EntryPtr; vous avez besoin de les jeter à la place EntryPtr *.

Edit 2: Comme l'a souligné Amit Kumar , vous aussi doivent changer le paramètre clé que vous envoyez à BSEARCH, ou vous devez comprendre que les conseils que vous recevez dans compareEntries ne pointent pas vers les mêmes types et aura besoin de deux typecasts différentes.

sizeof (entrée)

fonctionnerait. La plupart du temps sizeof doit être utilisé au lieu du type d'une instance.

sizeof (Entrée)

est préférable à

Entrée e;
sizeof (e);

ou

Entrée * e;
sizeof (* e);

tous donnent le même résultat.

#include "stdio.h"
class Entry {
  double e;
  int i;
};
int main() {
  Entry e;
  printf("%d\n", sizeof(e));
  printf("%d\n", sizeof(Entry));
  printf("%d\n", sizeof(*(&e)));
  return 0;
}

Lire la manuel attentivement.

Un résumé des points soulevés par d'autres, ainsi que quelques autres questions:

  • Votre utilisation de sizeof est correct.

  • Vous devriez passer un pointeur sur l'entrée contenant la clé que vous voulez regarder. En fait, la clé peut être quelque chose, et il sera transmis à la fonction de comparaison comme premier argument , et vous avez juste besoin de jeter les deux arguments bons types. (La fonction de comparaison doit correspondre encore à l'ordre les articles ont été triés par.)

  • Les moulages dans la fonction de comparaison ne sont pas correctes. La fonction de comparaison reçoit un pointeur vers l'élément (qui dans votre cas est un pointeur à l'entrée, d'où la fonction de comparaison reçoit des pointeurs vers des pointeurs à l'entrée).

  • Vous lancez le résultat du mauvais type. Là encore, la fonction renvoie un pointeur vers un élément dans le tableau (pointeur de pointeur vers l'entrée).

  • Vous ne vérifiez pas si le résultat est NULL, si la clé ne pas être là.

  • Vous pourriez probablement renoncer à un niveau d'indirection (avez-vous vraiment besoin d'un tableau de pointeurs au lieu d'un tableau d'entrées?)

  • Vous devriez le prendre comme un bon exemple de ce que les gens veulent dire quand ils parlent des vertus de type sécurité: dans votre code pratiquement tous les types sont mélangés et que vous faites des choses mauvaises avec mauvais types, encore pas une seule plainte du compilateur. C'est ce que vous obtenez si vous salissez avec void*, sauf si vous savez exactement ce que vous faites.

Pour le plaisir, ayant un tableau de pointeurs, il faut une quantité ridicule de indirection pour obtenir un résultat:

#include <cstdlib>
#include <string>
#include <iostream>

int compare_string(const void* a, const void* b)
{
    return ((const std::string*)a)->compare(**(const std::string**)b);
}

int main()
{
    std::string a("a"), b("b"), c("c");
    std::string* array[3] = { &a, &b, &c };
    std::string key = "b";
    std::string** result = (std::string**)bsearch(&key, array, 3, sizeof(std::string*), compare_string);
    if (result) std::cout << **result << '\n';
}

OMI, il prendrait moins de temps pour mettre en œuvre votre propre bsearch de type sécurisé, qu'il ne faut pour comprendre tout cela et l'ont testé et débogué.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top