【问题标题】:C - Linked List Segmentation Fault During DisplayC - 显示期间的链表分段错误
【发布时间】:2016-01-27 03:30:42
【问题描述】:

编辑 2:我意识到对于不在数据库中的任何查询,我都没有“未找到”结果。已进行更改以引入此功能。这是当前的测试和测试输出:

输入:

3
sam
99912222
tom
11122222
harry
12299933
sam
edward
harry

输出:

Not found

=0
Not found

=0
Not found

=0
Not found

=0
sam
=99912222
Not found

=0
Not found

=0
Not found
[Infinite loop continues]

编辑:我在 display() 的 while 循环中更改了一些内容。我现在得到一个无限循环打印“= 0”,除了通过搜索的第三个或第四个循环。嗯……

顺便说一句,感谢您提醒使用== 测试字符串。现在看起来很容易。


我进行了一些搜索,但仍然无法理解我的代码哪里出错了。我正在处理一项挑战,这将导致一个简单的电话簿程序。它将输入一个数字(要添加的条目数),然后是名称和相关的电话号码(没有破折号或句点)。添加条目后,用户可以按名称搜索条目,并以“name=number”格式显示数字。

代码在 display() 函数中使用 while 循环引发分段错误。我假设我正在尝试打印分配为 NULL 的内容,但我无法弄清楚我哪里出错了。任何帮助将不胜感激。

最后,挑战要求我在 EOF 之前阅读查询;但是,这让我感到困惑,因为我要接受来自标准输入的用户输入。标准输入的 EOF 是什么样的,只是一个寄存器返回 (\n)?

(PS:这是我第一次尝试链表,所以任何指针都将不胜感激。)

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

void add_entry(void);
void display(void);

struct phonebook {
        char name[50];
        int number;
        struct phonebook *next;
    };
    struct phonebook *firstp, *currentp, *newp;
    char tempname[50];

int main() {
    int N;
    firstp = NULL;
    scanf("%d", &N);
    for (int i = 0; i < N; i++) {
        add_entry();
    }
    display();

    return 0;
}

void add_entry(void) {
    newp = (struct phonebook*)malloc(sizeof(struct phonebook));
    if (firstp == NULL) firstp = currentp = newp;
    else {
        currentp = firstp;
        while (currentp->next != NULL)
            currentp = currentp->next;
        currentp->next = newp;
        currentp = newp;
    }
    fgets(currentp->name, 50, stdin);
    scanf("%d", &currentp->number);

    currentp->next = NULL;
}

void display(void) {
    while (strcmp(tempname, "\n") != 0) {
        currentp = firstp;
        fgets(tempname, 50, stdin);

        while (strcmp(currentp->name, tempname) != 0) {
            if (currentp->next == NULL) {
                printf("Not found\n");
                break;
            }
            currentp = currentp->next;
        }
        printf("%s=%d\n", currentp->name, currentp->number);
    }
}

【问题讨论】:

  • 这里有一个指针:int n = 0; int *pointer = &amp;n;。我总是很乐意提供帮助:)

标签: c linked-list segmentation-fault


【解决方案1】:

您的问题是您永远找不到您要查找的条目。表达式currentp-&gt;name != tempname 将始终为真,因为它们始终不相等。在 C 中,这个相等性测试不会编译成逐个字符的比较,而是编译成指向 currentp-&gt;nametempname 的指针的比较。由于它们永远不会位于相同的地址,因此它们永远不会相等。

改用!strcmp(currentp-&gt;name, tempname)

那么,你崩溃的原因是因为你到达了列表的末尾,所以currentp在你的循环之后将是NULL,然后你尝试打印NULL-&gt;nameNULL-&gt;number,实际上导致崩溃。

另外,另一方面,您可能希望开始使用局部变量,而不是对所有内容都使用全局变量。

【讨论】:

  • 谢谢。我已经做出了改变。无限循环是否可能是由于 tempname 末尾存在换行符?
  • @JoeyGrant:由于您使用相同的方法将列表中的名称输入为临时名称,因此似乎换行符应该在两者中都存在或缺失,所以听起来不像这应该是个问题。
  • @JoeyGrant:但是,您必须检查strcmp(...) == 0,而不是!= 0strcmp() 在字符串相等时返回零。
  • 虽然不相等,但我需要移动到链表中的下一个结构,对吗?
  • @JoeyGrant:确实如此。
【解决方案2】:

不确定这是否解决了问题,但是你不能直接用C中的!=比较字符串。你需要使用if( strcmp( string1, string2 ) == 0 ) 来检查。

fgets 不像 getchar 那样采用 EOF (= -1),但它确实包含 '\n' 并用 NULL (= 0) 填充其余部分,因此检查 EOF 并不是很有帮助,但是是的,您可以停止在 \n 或 NULL 之后。

【讨论】:

  • 这绝对有帮助。我已经编辑了手头的问题。现在我得到一个无限循环,只有 1 个正确显示 3 个循环。
  • 你在说:while (strcmp(tempname, "\n") != 0)?这不会按照您想要的方式工作,并且它将始终是无限的,除非您有一个条目是仅由 '\n' 组成的字符串。你根本不需要那个循环。 strcmp 以并行方式解析两个字符串(只是字符数组)并测试所有字符是否相等(在这种情况下它返回 0,否则返回一个表示差异的 int)。你最初想用这条线做什么?
  • 我需要程序继续接受搜索查询,直到(程序挑战描述的内容)EOF。我假设这意味着我会收到一个空字符串来终止这种循环。但是,由于无限输出循环的持续存在,这显然是错误的。考虑替代方案?
  • 哦,对了。抱歉, fgets 确实 也需要 EOF,它也需要 \n 这通常用于知道输入何时完成。在这种情况下,可以将 while 循环 != EOF 放在 fgets(tempname,...) 之后。您应该注意将 while 循环放在 读取 tempname 的输入值之后。就像下面说的那样,你不应该在这里使用全局变量——一般来说,它们是一个坏主意,因为很难跟踪它们,而且你最终如何把循环放在错误的地方......跨度>
猜你喜欢
  • 2020-07-17
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-31
  • 1970-01-01
  • 2013-10-21
  • 2012-06-12
相关资源
最近更新 更多