CS50中的拼写错误

时间:2020-04-24 15:21:05

标签: c cs50

当前,我正在pset5上工作,每当尝试编译时,都会遇到分段错误。我找不到错误所在,非常感谢这里专家的帮助。提示错误是完全可以的。

代码:

// Implements a dictionary's functionality

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "dictionary.h"

int word_count = 0;

// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

// Number of buckets in hash table
const unsigned int N = 27;

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // Converting word to lower case
    char *lower_word = NULL;
    strcpy(lower_word, word);
    int len = 0;
    len = sizeof(lower_word);
    for (int i = 0; i < len; i++)
    {
        lower_word[i] = tolower(lower_word[i]);
    }

    node *head = NULL;
    node * cursor = NULL;
    cursor = head;

    while (cursor != NULL)
    {
        cursor = head;
        if (cursor -> word == lower_word)
        {
            return true;
        }
        else
        {
            cursor = cursor -> next;
        }
    }
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    // TODO
    // From: http://www.cse.yorku.ca/~oz/hash.html
    unsigned long sdbm(char *word);
    {
        unsigned long hash = 0;
        int c;
        while ((c = *word++))
        {
            hash = c + (hash << 6) + (hash << 16) - hash;
            // Deleted free(word);

        }
        return hash;
    }
    return 0;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Opening the file
    FILE *dict = fopen(dictionary, "r");
    if (dict == NULL)
    {
        return false;
    }

    // Read strings from file
    char word[LENGTH + 1];

    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }

    while (fscanf(dict, "%s", word) == EOF)
    {
        // Create a new node
        node *n = malloc(sizeof(node));
        n -> next = NULL;

        if (n == NULL)
        {
            return 1;
        }

        // Insert word into node
        int x = hash(word);

        strcpy(n -> word, word);

        // Set position x in table equal to node

        if(table[x] == NULL)
        {
            table[x] = n;
        }
        else
        {
            n = table[x];
            table[x] = n;
        }

        // Count word for size function
        word_count++;
    }
    fclose(dict);
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    // TODO
    int table_size = 0;
    table_size = sizeof(table)/sizeof(table[0]);
    int count = 0;
    for (int i = 0; i < table_size; i++)
    {
        count++;
    }
    return count;
    return 0;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    // TODO
    int table_size = 0;
    table_size = sizeof(table)/sizeof(table[0]);

    node *cursor = NULL;
    node* tmp = NULL;
    for (int i = 0; i < table_size; i++)
    {
        while (cursor != NULL)
        {
            tmp = cursor;
            cursor = cursor -> next;
            free(tmp);
        }
    }
    return true;
}

输入:

./speller texts/lalaland.txt

输出:

MISSPELLED WORDS

Segmentation fault

有人遇到过CS50 pset5吗?有关更多信息,请参阅:https://cs50.harvard.edu/x/2020/psets/5/speller/

我看了很多遍演练,也看过短裤,但是我没有进步。

更新检查功能:

{
    // Hash word to obtainhash value

    int bucket = hash(word);

    // Traverse linked list and look for the word using strcmp

    node *cursor = NULL;
    node *head = table[bucket];
    cursor = head;

    while (cursor != NULL)
    {
        if (strcasecmp(cursor -> word, word) == 0)
        {
            return true;
        }
        else
        {
            cursor = cursor -> next;
        }
    }
    return false;

}

更新2:

// Implements a dictionary's functionality

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <ctype.h>
#include "dictionary.h"

#define HASHMAX 1000

int word_count = 0;

// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

// Number of buckets in hash table
const unsigned int N = 143091;


// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // Hash word to obtainhash value

    int bucket = hash(word);

    // Traverse linked list and look for the word using strcmp

    node *cursor = NULL;
    node *head = table[bucket];
    cursor = head;

    while (cursor != NULL)
    {
        if (strcasecmp(cursor -> word, word) == 0)
        {
            return true;
        }
        else
        {
            cursor = cursor -> next;
        }
    }
    return false;

}

// Hashes word to a number
unsigned int hash(const char *word)
{
    // TODO
    // From: http://www.cse.yorku.ca/~oz/hash.html
    unsigned long sdbm(char *word);
    {
        unsigned long hash = 5381;
        int c;
        while ((c = *word++))
        {
            hash = c + (hash << 6) + (hash << 16) - hash;
            // Deleted free(word);

        }
        return hash % HASHMAX;
    }
    return 0;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Opening the file
    FILE *dict = fopen(dictionary, "r");
    if (dict == NULL)
    {
        return false;
    }

    // Read strings from file
    char word[LENGTH + 1];

    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }

    while (fscanf(dict, "%s", word) != EOF)
    {
        // Create a new node
        node *n = malloc(sizeof(node));
        n -> next = NULL;

        if (n == NULL)
        {
            return 1;
        }

        // Insert word into node
        int x = hash(word);

        strcpy(n -> word, word);

        // Set position x in table equal to node

        if(table[x] == NULL)
        {
            table[x] = n;
        }
        else
        {
            n = table[x];
            table[x] = n;
        }

        // free(n);

        // Count word for size function
        word_count++;
    }
    fclose(dict);
    return true;
}




// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    // TODO
    int table_size = sizeof(table)/sizeof(table[0]);
    int count = 0;
    for (int i = 0; i < table_size; i++)
    {
        count++;
    }
    return count;
    return 0;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    // TODO
    int table_size = sizeof(table)/sizeof(table[0]);
    node *cursor = NULL;
    node* tmp = NULL;
    for (int i = 0; i < table_size; i++)
    {
        node *head = table[i];
        while (cursor != NULL)
        {
            tmp = cursor;
            cursor = cursor -> next;
            free(tmp);
        }
    }
    return true;
}

结果:

WORDS MISSPELLED:     17263
WORDS IN DICTIONARY:  143091
WORDS IN TEXT:        17756
TIME IN load:         0.02
TIME IN check:        0.01
TIME IN size:         0.00
TIME IN unload:       0.00
TIME IN TOTAL:        0.03

1 个答案:

答案 0 :(得分:1)

错误的最直接原因:NULL是一个常量,表示它无法更改,此行char *lower_word = NULL;lower_word设置为NULL,此行strcpy(lower_word, word);试图对其进行更改。段故障。

也许考虑简单地遍历单词并将每个字符设置为较低的“就位”。

编辑后:

table被分配给N(27)个元素。 hash函数返回的值 WAY 大于27。您可以将哈希函数更改为简单的字母索引(类似于tolower(word[i]) - 'a'),也可以使用模数({{ 1}})运算符以限制存储区大小。

这些可能不是程序中的唯一问题,但是当然,必须先修复段错误,然后才能取得真正的进展。 %是您的朋友(使用小词典更容易使用!)