CS50 Pset5: код не может быть скомпилирован из-за сбоя компоновщика - PullRequest
0 голосов
/ 28 марта 2020

Я только что закончил sh, написав простой код для Pset5 speller, просто чтобы проверить, способен ли мой код компилироваться. Код записывается в заголовочный файл. Однако, когда я пытаюсь скомпилировать файл, появляется ошибка clang-7: error: linker command failed with exit code 1. Основываясь на моем поверхностном понимании того, что читают онлайн, он говорит, что эта ошибка возникнет, если я объявлю и вызову функцию, у которой нет определения. Любая помощь приветствуется. Вот мой код:

        #include <stdlib.h>
        #include <string.h>
        #include <ctype.h>
        #include <stdio.h>

        #include "dictionary.h"

        // 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 = 26;

        // Hash table
        node *table[N];

        // Returns true if word is in dictionary else false
        //uses the hash table to check
        bool check(const char *word)
        {
            int hashindex = hash(word);
            node *tmp = table[hashindex];
            while (tmp->next != NULL)
            {
                if (strcmp(word, tmp->word) == 0)
                {
                    return true;
                }
                tmp = tmp->next;
            }
            return false;
        }

        // Hashes word to a number
        unsigned int hash(const char *word)
        {
            //hashing the first letter of the string
            unsigned int value1 = (int) *(word);
            unsigned int value2;
            if (isupper(value1))
            {
                value2 = tolower(value1);
            }
            else
            {
                value2 = value1;
            }
            int hashvalue = value2 % 97;
            return hashvalue;
        }

        // Loads dictionary into memory, returning true if successful else false
        //hashes the words in the dictionary file
        bool load(const char *dictionary)
        {
            // open dictionary file to load
            FILE *file = fopen(dictionary, "r");
            if (file == NULL)
            {
                printf("Could not open %s.\n", dictionary);
                return false;
            }

            //making an array that can store scanned words from the dictionary
            char dictionaryword[LENGTH];
            //initializing all the buckets in the table
            for (int i = 0; i < N; i++)
            {
                table[i] = NULL;
            }
            //loop to read the word one-by-one
            while(fscanf(file, "%s", dictionaryword) != EOF)
            {
                //creating a new node to store the word
                node *n = malloc(sizeof(node));
                if (n == NULL)
                {
                    return false;
                }
                strcpy(n->word, dictionaryword);
                n->next = NULL;
                //hashing the word to determine which bucket to store it in
                int hashindex = hash(n->word);
                //checking for any collisions
                if (table[hashindex] == NULL)
                {
                    table[hashindex] = n;
                }
                else
                {
                    //adding new node from the end
                    node *tmp = table[hashindex];
                    while (tmp->next != NULL)
                    {
                        tmp = tmp->next;
                    }
                    tmp->next = n;
                }
                memset (dictionaryword, 0, LENGTH);
            }
            return true;
        }

        // Returns number of words in dictionary if loaded else 0 if not yet loaded
        //the biggest number in the hash table
        unsigned int size(void)
        {
            //iterate over each bucket, assuming all the buckets are filled
            unsigned int counter = 0;
            for (int i = 0; i < N; i++)
            {
                node* tmp = table[i];
                while(tmp->next != NULL)
                {
                    tmp = tmp->next;
                    counter++;
                }
            }
            return counter;
        }

        // Unloads dictionary from memory, returning true if successful else false
        bool unload(void)
        {
            for (int i = 0; i < N; i++)
            {
                //if the bucket is not filled, memory is leaked somewhere
                if (table[i] == NULL)
                {
                    return false;
                }
                while (table[i] != NULL)
                {
                    node *tmp = table[i]->next;
                    free(table[i]);
                    table[i] = tmp;
                }
            }
            return true;
        }

РЕДАКТИРОВАТЬ: Это заголовочный файл

#ifndef DICTIONARY_H
        #define DICTIONARY_H

        #include <stdbool.h>

        // Maximum length for a word
        // (e.g., pneumonoultramicroscopicsilicovolcanoconiosis)
        #define LENGTH 45

        // Prototypes
        bool check(const char *word);
        unsigned int hash(const char *word);
        bool load(const char *dictionary);
        unsigned int size(void);
        bool unload(void);

        #endif // DICTIONARY_H
...