程序没有 exit/terminated 正确(CS50 Speller)
Program didnt exit/terminated correctly (CS50 Speller)
该程序对与给定词典(CS50:Pset5 Speller)配对的文本运行拼写检查。字典文件是txt文件形式,以hashtable.
的形式加载到内存中
检查函数采用从文本文件中读取的单词作为参数。该词被散列并与给定的单个散列 table 中存在的任何元素进行比较。如果一个词存在,它 return 为真,否则为假。
Hash 正在散列任何给定的单词,而 Load 函数正在将字典中的单词加载到散列中单词的相应散列索引 table。加载函数将指向字典的指针作为参数。
Size 函数通过指向现有散列来测量字典的大小 table。
卸载函数重复散列的每个可能索引 table,同时调用 ClearNodes,它检查连接到散列 table.
的链表中的内容
我已经尝试将文本和词典的大小调整到更小的尺寸,并且我还尝试在调用单个函数之前和之后放置我的断点(因为以某种方式将断点放置在 main() loads the dictionary
和 [=13= 之后] ,然后在调试器中手动按下 step-over
直到 main()
完成,设法使程序正常终止)。对于较小尺寸的字典和文本,我没有发现任何导致函数不是 return 值的相似之处。请记住,此时卸载函数假定始终 return 为真,并且尚未完成。
非常感谢帮助。
// Implements a dictionary's functionality
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// TODO: Choose number of buckets in hash table
const unsigned int N = 17576;
// Hash table
node *table[N];
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
//Create Word Hash Value
int WordHashIndex = hash(word);
node *Temp = table[WordHashIndex];
//Jump to Hash Index
while(Temp != NULL)
{
if(strcasecmp(Temp -> word, word) != 0)
{
Temp = Temp -> next;
}
else
{
return true;
}
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO: Improve this hash function
if(word[1] == '[=11=]')
{
return (toupper(word[0]) - 65);
}
else if(word[2] == '[=11=]')
{
return ((toupper(word[0]) - 65) + ((((toupper(word[1]) - 65) * 26) > -1) ? ((toupper(word[1]) - 65) * 26) : 0));
}
else
{
return ((toupper(word[0]) - 65) + ((((toupper(word[1]) - 65) * 26) > -1) ? ((toupper(word[1]) - 65) * 26) : 0) + ((((toupper(word[2]) - 65) * 676) > -1) ? ((toupper(word[2]) - 65) * 676) : 0));
}
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// TODO
int HashedIndex = 0;
char TempWord[LENGTH + 1];
int CharLengthCounter = 0;
FILE *LoadedDictionary = fopen(dictionary, "r");
if(LoadedDictionary == NULL)
{
return false;
}
while(fscanf(LoadedDictionary, "%s", TempWord) != EOF)
{
HashedIndex = hash(TempWord);
node *TempNode = NULL;
//Jump To HashedIndex
if(table[HashedIndex] != NULL)
{
TempNode = malloc(sizeof(node));
TempNode -> next = table[HashedIndex] -> next;
table[HashedIndex] -> next = TempNode;
strcpy(TempNode -> word, TempWord);
}
else
{
TempNode = malloc(sizeof(node));
table[HashedIndex] = TempNode;
strcpy(table[HashedIndex] -> word, TempWord);
}
}
if(LoadedDictionary != NULL)
{
free(LoadedDictionary);
return true;
}
else
{
return false;
}
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// TODO
node *Temp;
int DictSize = 0;
for(int Counter = 0; Counter < N; Counter++)
{
Temp = table[Counter];
if(Temp != NULL)
{
DictSize++;
while(Temp -> next != NULL)
{
Temp = Temp -> next;
DictSize++;
}
}
else
{
continue;
}
}
if(DictSize != 0)
{
return DictSize;
}
else
{
return 0;
}
}
//Check Node Data and Length Inside Each Table
bool ClearNodes(node *CurrentIndex)
{
if(CurrentIndex != NULL)
{
if(CurrentIndex -> next != NULL)
{
if(ClearNodes(CurrentIndex -> next))
{
free(CurrentIndex);
return true;
}
}
else
{
free(CurrentIndex);
return true;
}
}
return false;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
// TODO
int TableElementsCheck = 0;
for(int Counter = 0; Counter < N; Counter++)
{
ClearNodes(table[Counter]);
}
return true;
}
你的问题在函数中至少有以下错误load
:
以下块是错误的:
else
{
TempNode = malloc(sizeof(node));
table[HashedIndex] = TempNode;
strcpy(table[HashedIndex] -> word, TempWord);
}
您忘记将 TempNode->next
设置为 NULL
。
此外,行
free(LoadedDictionary);
错了。您应该在函数 fopen
.
返回的 FILE *
上调用 fclose
而不是 free
修复这些错误后,输出显示正确:
MISSPELLED WORDS
A
is
not
a
此输出是正确的,因为您提供的字典中不存在这些词。单词 cat
和 caterpillar
没有打印错误,因为它们在字典中。
该程序对与给定词典(CS50:Pset5 Speller)配对的文本运行拼写检查。字典文件是txt文件形式,以hashtable.
的形式加载到内存中检查函数采用从文本文件中读取的单词作为参数。该词被散列并与给定的单个散列 table 中存在的任何元素进行比较。如果一个词存在,它 return 为真,否则为假。
Hash 正在散列任何给定的单词,而 Load 函数正在将字典中的单词加载到散列中单词的相应散列索引 table。加载函数将指向字典的指针作为参数。
Size 函数通过指向现有散列来测量字典的大小 table。
卸载函数重复散列的每个可能索引 table,同时调用 ClearNodes,它检查连接到散列 table.
的链表中的内容我已经尝试将文本和词典的大小调整到更小的尺寸,并且我还尝试在调用单个函数之前和之后放置我的断点(因为以某种方式将断点放置在 main() loads the dictionary
和 [=13= 之后] ,然后在调试器中手动按下 step-over
直到 main()
完成,设法使程序正常终止)。对于较小尺寸的字典和文本,我没有发现任何导致函数不是 return 值的相似之处。请记住,此时卸载函数假定始终 return 为真,并且尚未完成。
非常感谢帮助。
// Implements a dictionary's functionality
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// TODO: Choose number of buckets in hash table
const unsigned int N = 17576;
// Hash table
node *table[N];
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
//Create Word Hash Value
int WordHashIndex = hash(word);
node *Temp = table[WordHashIndex];
//Jump to Hash Index
while(Temp != NULL)
{
if(strcasecmp(Temp -> word, word) != 0)
{
Temp = Temp -> next;
}
else
{
return true;
}
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO: Improve this hash function
if(word[1] == '[=11=]')
{
return (toupper(word[0]) - 65);
}
else if(word[2] == '[=11=]')
{
return ((toupper(word[0]) - 65) + ((((toupper(word[1]) - 65) * 26) > -1) ? ((toupper(word[1]) - 65) * 26) : 0));
}
else
{
return ((toupper(word[0]) - 65) + ((((toupper(word[1]) - 65) * 26) > -1) ? ((toupper(word[1]) - 65) * 26) : 0) + ((((toupper(word[2]) - 65) * 676) > -1) ? ((toupper(word[2]) - 65) * 676) : 0));
}
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// TODO
int HashedIndex = 0;
char TempWord[LENGTH + 1];
int CharLengthCounter = 0;
FILE *LoadedDictionary = fopen(dictionary, "r");
if(LoadedDictionary == NULL)
{
return false;
}
while(fscanf(LoadedDictionary, "%s", TempWord) != EOF)
{
HashedIndex = hash(TempWord);
node *TempNode = NULL;
//Jump To HashedIndex
if(table[HashedIndex] != NULL)
{
TempNode = malloc(sizeof(node));
TempNode -> next = table[HashedIndex] -> next;
table[HashedIndex] -> next = TempNode;
strcpy(TempNode -> word, TempWord);
}
else
{
TempNode = malloc(sizeof(node));
table[HashedIndex] = TempNode;
strcpy(table[HashedIndex] -> word, TempWord);
}
}
if(LoadedDictionary != NULL)
{
free(LoadedDictionary);
return true;
}
else
{
return false;
}
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// TODO
node *Temp;
int DictSize = 0;
for(int Counter = 0; Counter < N; Counter++)
{
Temp = table[Counter];
if(Temp != NULL)
{
DictSize++;
while(Temp -> next != NULL)
{
Temp = Temp -> next;
DictSize++;
}
}
else
{
continue;
}
}
if(DictSize != 0)
{
return DictSize;
}
else
{
return 0;
}
}
//Check Node Data and Length Inside Each Table
bool ClearNodes(node *CurrentIndex)
{
if(CurrentIndex != NULL)
{
if(CurrentIndex -> next != NULL)
{
if(ClearNodes(CurrentIndex -> next))
{
free(CurrentIndex);
return true;
}
}
else
{
free(CurrentIndex);
return true;
}
}
return false;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
// TODO
int TableElementsCheck = 0;
for(int Counter = 0; Counter < N; Counter++)
{
ClearNodes(table[Counter]);
}
return true;
}
你的问题在函数中至少有以下错误load
:
以下块是错误的:
else
{
TempNode = malloc(sizeof(node));
table[HashedIndex] = TempNode;
strcpy(table[HashedIndex] -> word, TempWord);
}
您忘记将 TempNode->next
设置为 NULL
。
此外,行
free(LoadedDictionary);
错了。您应该在函数 fopen
.
FILE *
上调用 fclose
而不是 free
修复这些错误后,输出显示正确:
MISSPELLED WORDS
A
is
not
a
此输出是正确的,因为您提供的字典中不存在这些词。单词 cat
和 caterpillar
没有打印错误,因为它们在字典中。