C 创建索引,我做错了什么?

C 创建索引,我做错了什么?,c,string,pointers,indexing,struct,C,String,Pointers,Indexing,Struct,我创建了下一个索引代码: #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> struct wordlist { char *value; int *lines; struct wordlist *next; }; int compare (struct wordlist *one , struct wordlist

我创建了下一个索引代码:

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

struct wordlist {
    char *value;
    int *lines;
    struct wordlist *next;
};

int compare (struct wordlist *one , struct wordlist *two) {
    return strcmp(one->value, two->value);
}

void add(struct wordlist **pp, char *value, int line) {

    struct wordlist *new;
    new = malloc(sizeof(*new));
    new->value = value;

    for ( ; *pp != NULL; pp = &(*pp)->next) {
        if (compare(*pp, new) == 0) {
            return;
        }
        else if (compare(*pp, new) > 0) {
            break;
        }
    }

    new->next = *pp;
    *pp = new;
}

void display(struct wordlist *ptr) {

    for (; ptr != NULL; ptr = ptr->next) {
        printf("%s\n", ptr->value);
    }
}
它假设每一个不是a-z或a-z字符的东西都会打断字符串

当我给他一个字符串来调试我的代码时

yonatan.lif

他正在印刷:

lif yonatanp

我的输出应该是

利夫约纳坦

(我不希望有“p”或任何其他字符)

只要输入长度大于字符串后面不应该存在的字符长度

它可以工作,但它的工作方式与我用长输入描述的一样,我不知道为什么。你能帮我找出我做错了什么吗

谢谢所有的帮助

使用大多数标准头提供的函数时,C中的字符串必须以null结尾,例如
strcmp()
printf()
,等等。从的参考号:

此函数开始比较每个字符串的第一个字符。 […]它将继续[…],直到找到终止的空字符为止 达到

这是导致您正在调用的未定义行为的原因,但不是null终止字符串。为此,请将代码修改为:

word[i] = '\0';
i = -1;
add(&root, word, line);
现在,您的字将以null结尾,您的程序将正常运行


下面是您的程序发生了什么的场景(您应该拿一张纸和一支铅笔,画下您的代码下次做什么)

  • word
    指向“yonatan”
  • 您输入了“.”,因此调用了
    add()
  • 此时将创建一个
    新的
    结构,它的
    下一个
    成员将位于该结构中 设置为
    root
    ,即
    NULL
    value
    word
    指向的位置, 和
    …这个成员将保持未初始化状态(应该是 可能设置为0,但您更清楚)
  • 我们继续,现在
    word
    忘记了“yonatan”并指向 “lif”
  • 再次调用
    add()
    ,其中创建另一个
    new
    struct,使用 它的
    到“lif”,它的
    下一个
    到先前创建的 结构,在步骤3。这就是为什么你的话会被保留下来 从他们的输入顺序<代码>行将再次保持未初始化状态
  • 调用了
    display()
    ,但
    %s
    格式查找空值 终止符停止,这是字符串可能缺少的,因此调用 未定义的行为(您看到的垃圾角色,如 “p”)
  • 现在您应该问一下,我的for循环和
    compare()
    函数怎么样?一旦第二次调用
    add()
    ,并且调用了
    compare()
    函数,但没有以null结尾的字符串,您将进入该循环
    strcmp()
    无法正确执行其工作,我猜它会返回一个垃圾正值,从而中断循环


    PS:这不是问题,但可能会给读者带来困惑:

    char *word;
    word = malloc(sizeof(char*));
    
    为什么要为指针分配空间?你可能只是想说:

    word = malloc(sizeof(char));
    

    那么,当您调试代码时,您会看到什么呢?当我输入yonatan.lif时,我得到lif yonatanp1)CString需要在字符串末尾使用空终止符(
    '\0'
    )。哇,问题解决得太多了
    word=realloc(word,(I+1)*sizeof(char)建议:不要这样做。您的代码将调用realloc()onceper字符。相反:分配太多,并以更大的增量更改大小。顺便说一句:您的初始分配
    sizeof(char*)
    是错误的。(但无害)谢谢。“你应该拿一张纸和一支铅笔,画下你的代码下一次会做什么”,你要大胆地使用它。
    word = malloc(sizeof(char));