Pregunta

Estoy trabajando en una tarea en la que yo estoy obligado a utilizar matrices de char en lugar de cuerdas y qsort / bsearch. En mi llamado a bsearch a continuación, I saben que estoy pasando el tamaño incorrecto de entrada, pero no estoy seguro de cómo obtener el tamaño real, y mi función compareEntries por lo tanto, no es encontrar los objetos adecuados .

Puede alguien ayudarme a entender lo que me falta?

#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;
}
¿Fue útil?

Solución

¿Por qué no sizeof(Entry) trabajo?

cambió de nuevo - Creo que el tamaño debe ser el tamaño del puntero ....

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

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

Otros consejos

El problema es que la función de comparador utilizado en bsearch espera word a ser de tipo Entry* (o m_entries a ser de tipo char**).

Se hace saber que bsearch requiere una entrada ordenada, ¿verdad?

sizeof(m_entries[0]) se ve perfectamente bien para mí.

Edit: Ahora veo el problema. Su clase Dictionary contiene una matriz de punteros. El problema está en la función compareEntries, donde pasó elenco punteros a EntryPtr; que necesita para echarlos a EntryPtr * lugar.

Editar 2: Como se ha señalado por Amit Kumar , también necesidad de cambiar el parámetro clave que envíe a bsearch, o si tiene que darse cuenta de que los punteros que se reciben en compareEntries no están apuntando a los mismos tipos y necesitará dos typecasts diferentes.

sizeof (Entrada) funcionaría. Parcialmente sizeof se debe utilizar en el tipo en lugar de una instancia.

sizeof (Entrada)

es preferible

Entrada electrónico;
sizeof (e);

o

Entrada * e;
sizeof (* e);

todos dan el mismo resultado.

#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;
}

rel="nofollow cuidado.

Un resumen de las observaciones hechas por otros, así como un par de cuestiones:

  • Su uso de sizeof es la correcta.

  • Usted debe pasar un puntero a la entrada que contiene la clave que desea buscar. En realidad, la clave puede ser cualquier cosa, y se pasa a la función de comparación como el primer argumento y sólo tiene que echar a ambos argumentos tipos correctos. (La función de comparación debe todavía corresponder al orden los artículos fueron ordenados por.)

  • Los moldes en la función de comparación no son correctos. La función de comparación recibe un puntero al elemento (que en su caso es un puntero a la entrada, por lo tanto, la función de comparación recibe punteros a punteros a la entrada).

  • Lanzas el resultado al tipo equivocado. De nuevo, la función devuelve un puntero a un elemento de la matriz (puntero a puntero a la entrada).

  • No comprueba si el resultado es NULL, la clave no debe estar allí.

  • Probablemente se podría renunciar a un nivel de indirección (lo que realmente necesita una matriz de punteros en lugar de una serie de entradas?)

  • Usted debe tomar como un buen ejemplo de lo que la gente quiere decir cuando hablan de las virtudes de la seguridad de tipos: en su código de prácticamente todos los tipos se mezclan y que está haciendo cosas mal con mal tipos, sin embargo, ni una sola queja de que el compilador. Eso es lo que se obtiene si se metan con void*, a menos que sepa exactamente lo que está haciendo.

Para el gusto de hacerlo, tiene un conjunto de punteros se necesita una cantidad ridícula de indirección para obtener un resultado:

#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, tomaría menos tiempo para implementar su propio bsearch de tipo seguro, que se necesita para entender todo esto y lo han probado y depurado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top