C 为什么printf函数会影响我的拼写程序?
我正在使用一个来自internet的哈希函数,当我在return语句之前使用print函数时,它会使我的程序正确无误,但如果我删除它,它会再次出现错误。。。就像字面上令人沮丧,因为我可以做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
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);