2014-12-02 53 views
2

我真的可以使用一些我一直在努力的地址簿程序的帮助。我正在使用C中的双向链表。我试图在用户输入的位置将列表添加到列表中,从位置0开始。位置不会输入超出范围。 (在位置0之前没有插入位置1之前的位置等)。位置可以重复,但是:将新节点插入到先前位置占用者之前的位置。 (例如:如果位置1有x,并且新节点插入y位置1,则位置1现在有y,位置2有x)双向链接列表C,在特定位置插入

我需要输入用户输入的位置编号并检索当前人员在那个位置,但我不能完全正确。另外,如果你想看看这个插件的功能,那么我也包含了插入功能,因为它也不能正常工作。谢谢你的帮助!

编辑:主要的问题,现在是我寻找pPersonCur代码失败时位置== 1。此外,插入函数不按正确的顺序中的位置不移动的进入的东西(最新插入较旧的插入正确)。然而,破碎的pPersonCur代码很难诊断为什么这是确切的。

addressbook.h摘录:

typedef struct person Person; 
struct person { 
    char lastName[255]; 
    char firstName[255]; 
    char email[255]; 
    char phoneNumber[255]; 
    Person *pNext; 
    Person *pPrev; 
}; 

addressbook.c摘录:

#include "addressbook.h" 

Person * InsertPerson(Person * pPersonCur) { 
    Person * pPersonNew; 

    /* data gathered for CreatePerson() function here */ 

    pPersonNew = CreatePerson(pLastName, pFirstName, pEmail, pPhoneNumber); 

    if (pPersonCur) 
    { 
     pPersonNew->pNext = pPersonCur; 
     pPersonNew->pPrev = pPersonCur->pPrev; 
     pPersonCur->pPrev = pPersonNew; 
     if (pPersonNew->pPrev) 
      pPersonNew->pPrev->pNext = pPersonNew; 
    } else 
    { 
     pPersonNew->pPrev = pFirst; 
     pPersonNew->pNext = NULL; 
     if (pFirst) 
      pFirst->pNext = pPersonNew; 
    } 
    return (pPersonNew); 
} 

main.c中摘录:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "addressbook.h" 

Person *pFirst; /* First name in list */ 

int main(void) { 

     Person *pPersonCur = NULL; /* current Person */ 
     int bDone = 0, position = 0, counter = 0; 

     pFirst = NULL; 

    printf("Ready\n"); 

    while (!bDone) { 
     char input = getchar(); 
     switch (input) { 
     case 'a': 
      counter = 0; 
      scanf("%d", &position); /* Where desired position is entered */ 
      if (position == 0) { 
       if (pFirst) { 
        if (pFirst->pNext) { 
         pPersonCur = pFirst->pNext; 
        } 
       } else { 
        pPersonCur = pFirst; 
       } 
      } else { 
       pPersonCur = pFirst->pNext; 
       while (counter < position) { 
        pPersonCur = pPersonCur->pNext; 
        counter++; 
       } 
      } 
      InsertPerson(pPersonCur); /* Takes in person at desired position, return value is new inserted person */ 
      break; 
     /* Some other cases here */ 
     case 'q': 
      bDone = 1; 
      break; 
     } 
    } 
/* Rest of code */ 
+0

'InsertPerson'的返回值是有原因的。你可能想要利用它。 – WhozCraig 2014-12-02 21:10:54

+2

这不是一个真正的问题......它出错了?什么“不完全正确”? 我建议你调试它,并在整个列表中有一个手表,然后你可能会看到它什么时候出错和/或被破坏,或者,*以什么方式*它是“出错了”! 祝你好运! – noelicus 2014-12-02 21:16:19

+0

@WhozCraig是的,我尝试过,因为它被用于类似的问题,但我不能想象它在这种情况下使用太多考虑到我必须明确输入位置。 – 2014-12-02 21:25:36

回答

2

如此看来,你从来没有分配一个值pFirst
当位置不是0时,行pPersonCur = pFirst->pNext;被执行并且pFirst在这个地方仍然是NULL

添加一个条件到你的插入函数来检查列表的头是否被分配。

Person * InsertPerson(Person * pPersonCur) { 
    . . . 
    else 
    { 
     pPersonNew->pPrev = pFirst; 
     pPersonNew->pNext = NULL; 
     if (pFirst) 
      pFirst->pNext = pPersonNew; 
     else 
      pFirst = pPersonNew; // If pFirst is not assigned, assign it to newly created person 
    } 
    return (pPersonNew); 
} 

尽管如此,如果你碰巧打电话InsertPersonNULL的说法,你的代码就会把新Person后的第一个切名单关闭的其余部分。根据位置索引

if(pFirst) { 
    Person *last = pFirst; 
    while(last->pNext != NULL) { 
     last = last->pNext; 
    } 
    last->pNext = pPersonNew; 
    pPersonNew->pPrev = last; 
} 
else 
    pFirst = pPersonNew; 

插入可能会失败,以及如果你给一个位置:

为了把新Person到列表的末尾时NULL叫你可以使用这样的事情在你InsertPerson功能索引高于列表中的节点。应该添加某种安全检查。

pPersonCur = pFirst->pNext; 
while (counter < position && pPersonCur->pNext != NULL) { // If last node reached, stop the loop 
    pPersonCur = pPersonCur->pNext; 
    counter++; 
} 

此实现将增加新Person到列表的末尾,如果位置指数过高。