第一篇文章,在编码知识方面极为有限,对C来说是新手。温柔!我正处于"尝试"不同的事情让我越来越困惑。我需要有人正确的指导!
这个特殊的问题来自于我正在尝试的在线edX课程,最终在正确实施时,检查从文本文件中读入的给定单词('检查'功能)并将其与每个单词读取进行比较进入(来自'加载'函数)结构的链接列表。
我相信我正确地实现了加载功能,就像我使用gdb一样,因为我看到了我期待的内容,但我的问题和我的问题特别与检查功能有关。我仍然需要很多工具来完成我的代码,但在使用gdb进行测试时,我没有看到结构的char *成员的值与我预期的应该看到的相符。
使用gdb并单步执行'检查'函数并尝试访问我在load函数中创建的链表中的struct节点的dword
成员,我预计我应该看到char *成员的字符串。例如,我期待“" cat"分配给current->dword
,但我在测试时看到gdb:
〜(gdb)print current-> dword
$ 13 = 0xbfffede2" \ 004 \ b \ 214 \ 365 \ 372D \ 300 \ 355 \ 377 \ 277"
我的想法是,我仍然只是以某种方式访问某个地址而不是实际值,但我不知道为什么会这样。在load函数中创建节点时,会正确地为dword
成员分配一个值(至少在我单步执行gdb中的代码时可以告诉),但似乎无法访问正确地在检查功能。任何新手的帮助都将不胜感激!
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dictionary.h"
typedef struct node
{
char* dword;
struct node* next;
}
node;
// keep track of #of words in dictionary loaded
int wordCounter = 0;
// create root for hash table
node* root[26];
// create cursor to keep place in creating, pointing, and traversing through nodes
node* current = NULL;
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{
// size of word read into buffer
int wordSize = sizeof(word);
// prepare to make a new lowercase only word for comparison to lowercase only dictionary
char bufWord[wordSize];
// make it
for(int i = 0; i < wordSize; i++)
{
if (i == wordSize - 1)
{
bufWord[i] = '\0';
}
else
{
bufWord[i] = tolower(word[i]);
}
}
// hash word to achieve proper root node location
int hash = bufWord[0] - 97;
// point to the correct root node to begin traversing
current = root[hash];
// make sure there is even a word in hash table location
if(root[hash] == NULL)
{
return false;
}
else if(root[hash] != NULL)
{
// progress through the nodes until the last node's next pointer member is NULL
while(current != NULL)
{
// compare 1st letter only of current->dword[i] to bufWord[i] to save time
// if they don't match, return false
// if they do match then continue
\
char dictWord[wordSize];
// hold copy of struct member value to compare to dictWord
char* wordTemp = current->dword;
//
for(int i = 0; i < wordSize; i++)
{
dictWord[i] = wordTemp[i];
}
// do a spell check
if(strcmp(bufWord, dictWord) == 0)
{
return true;
}
else
{
// set current to the next node if any or NULL if it's already the last node in the list
current = current->next;
}
}
}
return false;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char* dictionary)
{
// buffer for reading in dictionary words
char wordIn[LENGTH + 1];
// open the dictionary file
FILE* newDict = fopen(dictionary, "r");
for (int i = 0; i < 27; i++)
{
root[i] = NULL;
}
// while there are words to read
while(fscanf(newDict, "%s ", wordIn) > 0)
{
// keep track of #of words for constant time read in size function
wordCounter++;
// hash the first letter for the location in root
int hash = wordIn[0] - 97;
// malloc space for a new node
node* newNode = malloc(sizeof(node));
// error check
if (newNode == NULL)
{
return false;
}
// set value member of node to current word
newNode->dword = wordIn;
// first insertion into linked list if that root node has not been used yet
if(root[hash] == NULL)
{
// sets to NULL
newNode->next = root[hash];
// link it
root[hash] = newNode;
}
else if(root[hash] != NULL)
{
// starts at the root
node* current = root[hash];
// insert into new beginning of list
newNode->next = current;
root[hash] = newNode;
}
}
fclose(newDict);
return true;
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
return wordCounter;
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
// TODO
return false;
}
答案 0 :(得分:1)
您的问题的根源是:
newNode->dword = wordIn;
wordIn
是load
中的本地数组。您将wordIn
的地址存储在节点的dword
中。当您从load
返回时,这些地址将不再有效。
您需要做的是为wordIn
中的字符串分配内存,将分配的内存分配给newNode->dword
并将wordIn
的内容复制到newNode->dword
。
如果您的平台提供非标准功能strdup
,您可以将以上行更改为:
newNode->dword = strdup(wordIn);
如果没有,则很容易实现:
char* strdup(char const* in)
{
char* r = malloc(strlen(in)+1);
strcpy(r, in);
return r;
}