我正在做一个家庭作业,我需要使用char数组而不是字符串和qsort / bsearch。在下面我对bsearch的调用中,我知道我传递了错误的Entry大小,但我不确定如何获得实际大小,因此我的compareEntries函数找不到正确的对象
任何人都可以帮助我理解我所缺少的东西吗?
#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;
}
答案 0 :(得分:2)
为什么sizeof(Entry)
无效?
再次更改 - 我认为大小应该是指针的大小....
EntryPtr tmp = new Entry("");
tmp->Word = word;
EntryPtr result = (EntryPtr) bsearch(tmp, m_entries,
m_numEntries, sizeof(EntryPtr), Dictionary::compareEntries);
答案 1 :(得分:1)
你知道bsearch
需要排序输入,对吗?
sizeof(m_entries[0])
对我来说非常好。
编辑:现在我看到了问题。 Dictionary类包含一个指针数组。问题出在compareEntries函数中,你将指针传递给EntryPtr
;你需要将它们转换为EntryPtr *
。
编辑2:正如Amit Kumar所指出的那样,你还需要更改发送给bsearch的关键参数,或者你需要意识到你在compareEntries中收到的指针不是指向相同的类型,需要两种不同的类型转换。
答案 2 :(得分:1)
问题是bsearch
中使用的比较器函数要求word
为Entry*
类型(或m_entries
为char**
类型)。
答案 3 :(得分:0)
仔细阅读manual。
其他人提出的观点摘要,以及更多问题:
您对 sizeof 的使用是正确的。
您应该将指针传递给包含您要查找的键的条目。实际上键可以是任何内容,它将作为第一个参数传递给比较函数,你只需要将两个参数都转换为正确的类型。 (比较函数应该仍然对应于项目的排序顺序。)
比较功能中的强制转换不正确。比较函数接收一个指向该元素的指针(在您的情况下是指向Entry的指针,因此比较函数接收指向Entry的指针)。
您将结果转换为错误的类型。该函数再次返回指向数组中元素的指针(指向Entry的指针)。
如果密钥不存在,则不检查结果是否为NULL。
你可能放弃一个间接层(你真的需要一个指针数组而不是一个条目数组吗?)
你应该把它当作人们在谈论类型安全的优点时所说的意思的一个很好的例子:在你的代码中几乎所有的类型都混淆了,你做错了类型的错误的东西,没有来自编译器的任何投诉。如果你弄乱void*
,那就是你得到的,除非你确切地知道你在做什么。
为了它的乐趣,拥有一个指针数组需要一个荒谬的间接量来获得结果:
#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';
}
IMO,实现自己的类型安全bsearch所需的时间比完成所有这些并将其测试和调试所花费的时间要少。
答案 4 :(得分:0)
sizeof(Entry)可行。大多数sizeof应该在类型而不是实例上使用。
<强>的sizeof(条目)强>
优于
输入e;
的sizeof(E); 强>
或
输入* e;
的sizeof(* E); 强>
都给出相同的结果。
#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;
}