我的链接列表程序不起作用

时间:2014-09-23 21:00:35

标签: c pointers doubly-linked-list

我正在尝试使用以下格式创建一个读取文本文件的程序:

Smith, John    
Johnson, Harry    
Clark, David

(这可以无休止地继续进行,并且我不需要在每个名称之间用空行,我只是为了清晰起见而这样写了)

文本文件的每一行都包含:last namefirst name。链表应将每个名字和姓氏存储为名称节点。我相信我的通用架构应该可行,但是,随着程序的执行,pCurrentpHead之类的变量似乎被覆盖而没有被重新分配。我离开了一个乱糟糟的链接列表,我从来没有见过这样的东西。任何人都可以发现我的架构或其他任何导致此程序无法按预期工作的缺陷。感谢

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

#include <string.h>

struct nameNode {
    char* first;
    char* last;
    struct nameNode* pNext;
    struct nameNode* pPrev;
};

struct nameNode* pHead, *pLast;
char firstName[50], lastName[50];

void insert_end(char* first, char* last) {
    struct nameNode* var = NULL, *temp = NULL;

    var = (struct nameNode*)malloc(sizeof(struct nameNode));

    var->first = first;
    var->last = last;
    if (pHead == NULL) {
        pHead = var;
        pHead->pPrev = NULL;
        pHead->pNext = NULL;
        pLast = pHead;
    } else {
        pLast = pHead;
        while (pLast != NULL) {
            temp = pLast;
            pLast = pLast->pNext;
        }

        pLast = var;
        temp->pNext = pLast;
        pLast->pPrev = temp;
        pLast->pNext = NULL;
        printf("Phead is %s\n", pHead);
    }
}

int main() {
    char file[100];
    printf("Enter input file ");
    scanf("%s", file);
    FILE* in_file = fopen(file, "r");

    while (fscanf(in_file, "%s %s", lastName, firstName) != EOF) {
        insert_end(lastName, firstName);
    }
}

2 个答案:

答案 0 :(得分:0)

您将自己的名字读入全局变量,并将地址存储在您阅读的位置。然后,您在同一个变量中读取一个新名称 - 然后再次存储相同的地址。

insert_end代码中更改此内容

var->first = strdup (first);
var->last = strdup (last);

副本存储在firstNamelastName中的字符串


轻微:实际上,你实际上有未定义的行为。您检查pHead是否为NULL,但您从未初始化它。确保在调用insert_end之前将其设置为NULL,或者只是将其初始化为

struct nameNode* pHead = NULL, *pLast = NULL;

同样轻微:添加一个没有temp的节点可以通过以下方式完成。事实上,你不需要一个循环,因为你已经知道pLast指向列表的末尾 - 但如果你想确保它是有效的,你可以利用最后的事实nameNode其成员pNext 必须为NULL:

pLast = pHead;
while (pLast->pNext != NULL) {
    pLast = pLast->pNext;
}
pLast->pNext = var;
pLast->pNext->pPrev = pLast;
pLast->pNext->pNext = NULL;
pLast = pLast->pNext;

同样轻微:要删除逗号,请在insert_node的开头附近插入:

if (first && first[0] && first[strlen(first)-1] == ',')
    first[strlen(first)-1] = 0;

请注意,这会从名为 first的参数中删除逗号,这实际上是姓氏。您可能希望在整个代码中纠正这一点。

同样也很轻微:您的scanf不是非常安全或具有错误恢复能力。它可能读取每个字符串的存储空间(49个字符),并且您正在检查文件结尾但不是参数计数不匹配。

这应该更好:

while ( fscanf(in_file, " %49[^,],%49s", lastName, firstName) == 2) {
    insert_end(lastName, firstName);
}

- 作为一个额外的奖励,它还会读取 - 然后忽略逗号。

答案 1 :(得分:0)

我认为您需要将nameNode结构定义如下:

struct nameNode {
  char[some_size] first; 
  char[some_size] last;
  struct nameNode* pNext;
  struct nameNode* pPrev;
};

插入节点时第一个和最后一个的malloc空间。