我制作了一个树形结构,从文件中读取单词并将它们注册到树中。但是enter()
无法正常工作。我使用gdb进行了调试并设置了一个断点线42.然后我输入了print *node
print *root
。
(gdb) print node
$9 = (struct node *) 0x603250
(gdb) print *node
$10 = {left = 0x0, right = 0x0, word = 0x0}
(gdb) print root
$11 = (struct node *) 0x0
(gdb) print *root
Cannot access memory at address 0x0
为什么root
没有任何意义?
为什么node->word
没有给出单词?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct node {
struct node *left;
struct node *right;
char *word;
};
static struct node *root = NULL;
void memory_error(void) {
fprintf(stderr, "Error: Out of memory\n");
exit(8);
}
char *save_string(char *string) {
char *new_string;
new_string = malloc((unsigned) (strlen(string) + 1));
if (new_string == NULL)
memory_error();
strcpy(new_string, string);
return (new_string);
}
void enter(struct node *node, char *word) {
int result;
if (node == NULL) {
node = malloc(sizeof(struct node));
if (node == NULL)
memory_error();
node->left = NULL;
node->right = NULL;
node->word = save_string(word);
return;
}
result = strcmp(node->word, word);
if (result == 0)
return;
if (result < 0)
enter(node->right, word);
else
enter(node->left, word);
}
void scan(char *name) {
char word[100];
int index;
int ch;
FILE *in_file;
in_file = fopen(name, "r");
if (in_file == NULL) {
fprintf(stderr, "Error: Unable to open %s\n", name);
exit(8);
}
while (1) {
while (1) {
ch = fgetc(in_file);
if (isalpha(ch) || (ch == EOF))
break;
}
if (ch == EOF)
break;
word[0] = ch;
for (index = 1; index < sizeof(word); index++) {
ch = fgetc(in_file);
if (!isalpha(ch))
break;
word[index] = ch;
}
word[index] = '\0';
enter(root, word);
}
fclose(in_file);
}
void print_tree(struct node *top) {
if (top == NULL)
return;
print_tree(top->left);
printf("%s\n", top->word);
print_tree(top->right);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Error: Wrong number of parameters\n");
fprintf(stderr, " on the command line\n");
fprintf(stderr, "Usage is:\n");
fprintf(stderr, " words 'file'\n");
exit(8);
}
scan(argv[1]);
print_tree(root);
return (0);
}
我给这个程序提供了以下文本作为参数“a.txt”。
apple
orange
lemon
banana
pine
stroberry
ruby
perl
python
c
答案 0 :(得分:5)
您从未指定root
。因此,它将始终保持NULL
。
请注意,在enter
中,您分配了一个节点,但实际上并未将结果节点保存在任何位置。您可能希望返回新节点并改为root = enter(root, word)
。
答案 1 :(得分:2)
正如@nneonneo指出的那样,您应该返回新修改的根,或者将root作为指针引用传递给void enter(struct node **node, char *word)
并使用enter(&root, word);
调用
答案 2 :(得分:1)
看起来您从未向root
分配任何值。请记住,C按值传递参数,因此当您从enter(root, word);
调用scan()
时,enter()
无法更改root
的值。但是,它改变了它的本地副本,但这还不够。
递归调用enter
时会出现同样的问题。
修复此问题的一种方法是将指针传递给节点指针,这样就可以这样改变:
enter(&root, word);
声明:
void enter(struct node **nodep, char *word) {
并调整其中node
的所有用途,使其成为*nodep
。
答案 3 :(得分:0)
您在enter()中分配节点,但由于它是通过复制而不是引用传递的,因此节点不会在函数外部更改。
返回新节点root = enter(root, word)
或通过引用传递:enter(&root, word)
,将enter的覆盖区域更改为void enter(struct node **node, char *word)
,将节点的所有实例更改为* node。