C 为什么printf函数会影响我的拼写程序?

C 为什么printf函数会影响我的拼写程序?,c,cs50,C,Cs50,我正在使用一个来自internet的哈希函数,当我在return语句之前使用print函数时,它会使我的程序正确无误,但如果我删除它,它会再次出现错误。。。就像字面上令人沮丧,因为我可以做printf(“asfasfnasfnk\n”),它将正确输出,但当我删除printf函数时,它又出现了错误 unsigned int hash(const char *word) { /* credits to... *https://www.reddit.com/r/cs50/commen

我正在使用一个来自internet的哈希函数,当我在return语句之前使用print函数时,它会使我的程序正确无误,但如果我删除它,它会再次出现错误。。。就像字面上令人沮丧,因为我可以做
printf(“asfasfnasfnk\n”),它将正确输出,但当我删除printf函数时,它又出现了错误

unsigned int hash(const char *word)
{
    /* credits to...
     *https://www.reddit.com/r/cs50/comments/1x6vc8/pset6_trie_vs_hashtable/
     */
    unsigned long hash = 0;
    int n  = strlen(word);

    for (int i = 0; i < n; i++)
    {
        hash = (hash << 2) ^ word[i];
    }
    return hash % N;
}
字典里的单词是猫和毛毛虫,课文里的单词是“猫不是毛毛虫”

职能:

// Implements a dictionary's functionality
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.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;

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

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // TODO
    int len = strlen(word);
    char *copy = malloc(sizeof(char) * len + 1);
    // change into lowercase the word
    for (int i = 0; i < len; i++)
    {
            copy[i] = tolower(word[i]);
    }
    // get the index by using the hash function
    int index = hash(copy);

    node *tmp = table[index];
    // check if the word is in the hash table
    while (tmp != NULL)
    {
        if (strcmp(tmp->word, copy) == 0)
        {
            free(copy);
            return true;
        }

        tmp = tmp->next;
    }

    free(copy);
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    /* credits to...
     *https://www.reddit.com/r/cs50/comments/1x6vc8/pset6_trie_vs_hashtable/
     */
    unsigned long hash = 0;
    int n  = strlen(word);

    for (int i = 0; i < n; i++)
    {
        hash = (hash << 2) ^ word[i];
    }
    return hash % N;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // TODO
    char *words = malloc(sizeof(char) * (LENGTH + 1));
    if (words == NULL)
    {
        return 1;
    }
    // initialize the hash table to NULL
    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }

    // open dictionary file
    FILE *indata = fopen(dictionary, "r");


    // 1 character for '\0' and another for '\n' because fgets takes a trailing new line
    // when it reads 'man' the value of words will be "man\n\0" so meaning 2 extra characters
    while (fgets(words, LENGTH + 2, indata) != NULL)
    {
        // get rid of the trailing new line from fgets
        words[strlen(words) - 1] = '\0';

        // allocate memory for the newNode
        node *newNode = malloc(sizeof(node));
        if (newNode == NULL)
        {
            return false;
        }

        // get the index by using the hash function
        int index = hash(words);

        strcpy(newNode->word, words);
        // make the newNode the head of the list
        newNode->next = table[index];
        table[index] = newNode;

    }

    // free memory and close the opened file
    free(words);
    fclose(indata);
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    // TODO
    // counter of words loaded
    unsigned int counter = 0;
    // loop through the hash table
    for (int i = 0; i < N; i++)
    {
        node *tmp = table[i];

        while (tmp != NULL)
        {
            counter++;
            tmp = tmp->next;
        }
    }
    return counter;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    // TODO
    // loop through the whole hash table
    for (int i = 0; i < N; i++)
    {
        while (table[i] != NULL)
        {
            node *tmp = table[i]->next;
            free(table[i]);
            table[i] = tmp;
        }
    }
    return true;
}
//实现字典的功能
#包括
#包括
#包括
#包括
#包括
#包括“dictionary.h”
//表示哈希表中的节点
类型定义结构节点
{
字符字[长度+1];
结构节点*下一步;
}
节点;
//哈希表中的桶数
常数无符号整数N=200000;
//哈希表
节点*表[N];
//如果单词在字典中,则返回true;否则返回false
布尔检查(常量字符*单词)
{
//待办事项
int len=strlen(字);
char*copy=malloc(sizeof(char)*len+1);
//把这个词改成小写
对于(int i=0;iword,copy)==0)
{
免费(副本);
返回true;
}
tmp=tmp->next;
}
免费(副本);
返回false;
}
//将单词散列为数字
无符号整数散列(常量字符*字)
{
/*归功于。。。
*https://www.reddit.com/r/cs50/comments/1x6vc8/pset6_trie_vs_hashtable/
*/
无符号长散列=0;
int n=strlen(字);
对于(int i=0;i下一步=表[索引];
表[索引]=新节点;
}
//释放内存并关闭打开的文件
免费(字);
fclose(indata);
返回true;
}
//如果已加载,则返回字典中的字数;如果尚未加载,则返回0
无符号整数大小(void)
{
//待办事项
//加载字计数器
无符号整数计数器=0;
//循环遍历哈希表
对于(int i=0;inext;
}
}
返回计数器;
}
//从内存中卸载字典,如果成功则返回true,否则返回false
bool卸载(无效)
{
//待办事项
//循环遍历整个哈希表
对于(int i=0;inext;
免费(表[i]);
表[i]=tmp;
}
}
返回true;
}
//待办事项
int len=strlen(字);
char*copy=malloc(sizeof(char)*len+1);
//把这个词改成小写
对于(int i=0;i
请注意,
malloc
中的
+1
。为什么会这样?这是为了给标记字符串结尾的终止零字节留出空间

假设字符串为“test”。然后
strlen
将返回4。您的循环将从0到3(含)进行迭代,复制单词中的四个字母

但您不会复制字符串末尾的终止零字节。当
hash
copy
上调用
strlen
时,谁知道它将得到什么值,因为您传递的不是合法字符串

for
循环中的条件更改为
i
//TODO
int len=strlen(字);
char*copy=malloc(sizeof(char)*len+1);
//把这个词改成小写
对于(int i=0;i
请注意,
malloc
中的
+1
。为什么会这样?这是为了给标记字符串结尾的终止零字节留出空间

假设字符串为“test”。然后
strlen
将返回4。您的循环将从0到3(含)进行迭代,复制单词中的四个字母

但您不会复制字符串末尾的终止零字节。当
hash
copy
上调用
strlen
时,谁知道它将得到什么值,因为您传递的不是合法字符串


for
循环中的条件更改为
i What's N(与N相对)?“它又被窃听了”具体如何?
word
是以NULL结尾的字符数组吗?请发布一个。你需要给我们足够的代码来复制错误。如果在没有调用此函数的代码的情况下无法复制错误,那么错误很可能与此代码一样出现在调用代码中。(更新:当然,它是。)这不是编译。它不是一个(关注极小值)。什么是N(相对于N)?“它又被窃听了”到底是怎么回事?
word
是以NULL结尾的字符数组吗?请发布一个。你需要给我们足够的代码来复制错误。如果在没有调用此函数的代码的情况下无法复制错误,那么错误很可能与此代码一样出现在调用代码中。(更新:当然,它是。)这不是编译。这不是一个(关注最小值)。好吧,妈的,非常感谢你已经调试了近3个小时,这是一个非常简单的错误。好吧,妈的,非常感谢你已经调试了近3个小时,这是一个非常简单的错误。。
// Implements a dictionary's functionality
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.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;

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

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // TODO
    int len = strlen(word);
    char *copy = malloc(sizeof(char) * len + 1);
    // change into lowercase the word
    for (int i = 0; i < len; i++)
    {
            copy[i] = tolower(word[i]);
    }
    // get the index by using the hash function
    int index = hash(copy);

    node *tmp = table[index];
    // check if the word is in the hash table
    while (tmp != NULL)
    {
        if (strcmp(tmp->word, copy) == 0)
        {
            free(copy);
            return true;
        }

        tmp = tmp->next;
    }

    free(copy);
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    /* credits to...
     *https://www.reddit.com/r/cs50/comments/1x6vc8/pset6_trie_vs_hashtable/
     */
    unsigned long hash = 0;
    int n  = strlen(word);

    for (int i = 0; i < n; i++)
    {
        hash = (hash << 2) ^ word[i];
    }
    return hash % N;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // TODO
    char *words = malloc(sizeof(char) * (LENGTH + 1));
    if (words == NULL)
    {
        return 1;
    }
    // initialize the hash table to NULL
    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }

    // open dictionary file
    FILE *indata = fopen(dictionary, "r");


    // 1 character for '\0' and another for '\n' because fgets takes a trailing new line
    // when it reads 'man' the value of words will be "man\n\0" so meaning 2 extra characters
    while (fgets(words, LENGTH + 2, indata) != NULL)
    {
        // get rid of the trailing new line from fgets
        words[strlen(words) - 1] = '\0';

        // allocate memory for the newNode
        node *newNode = malloc(sizeof(node));
        if (newNode == NULL)
        {
            return false;
        }

        // get the index by using the hash function
        int index = hash(words);

        strcpy(newNode->word, words);
        // make the newNode the head of the list
        newNode->next = table[index];
        table[index] = newNode;

    }

    // free memory and close the opened file
    free(words);
    fclose(indata);
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    // TODO
    // counter of words loaded
    unsigned int counter = 0;
    // loop through the hash table
    for (int i = 0; i < N; i++)
    {
        node *tmp = table[i];

        while (tmp != NULL)
        {
            counter++;
            tmp = tmp->next;
        }
    }
    return counter;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    // TODO
    // loop through the whole hash table
    for (int i = 0; i < N; i++)
    {
        while (table[i] != NULL)
        {
            node *tmp = table[i]->next;
            free(table[i]);
            table[i] = tmp;
        }
    }
    return true;
}
// TODO
int len = strlen(word);
char *copy = malloc(sizeof(char) * len + 1);
// change into lowercase the word
for (int i = 0; i < len; i++)
{
        copy[i] = tolower(word[i]);
}
// get the index by using the hash function
int index = hash(copy);