C 链表程序是';不能正确更新

C 链表程序是';不能正确更新,c,linked-list,xdebug,C,Linked List,Xdebug,我创建了一个程序,可以读取包含整数的文本文件。它应该在中读取这些整数,然后创建它们的链接列表。但是,我的程序的头指针会不断更新,即使只是尾部也会更新。有人知道这是为什么吗?输入文件可以是由空格或换行符分隔的整数。这是我的密码: #include<stdlib.h> #include<stdio.h> #include <string.h> /*THIS IS THE BASIC NAME STRUCTURE. IT CONTAINS A FIRST

我创建了一个程序,可以读取包含整数的文本文件。它应该在中读取这些整数,然后创建它们的链接列表。但是,我的程序的头指针会不断更新,即使只是尾部也会更新。有人知道这是为什么吗?输入文件可以是由空格或换行符分隔的整数。这是我的密码:

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

/*THIS IS THE BASIC NAME STRUCTURE. IT CONTAINS A FIRST AND LAST NAME VARIABLE*/
struct number {
    int * number;          //number
};
/*THIS IS THE BASIC NAME NODE STRUCTURE. IT CONTAINS A NAME STRUCT AS WELL AS STRUCT NAMENODES TO PREVIOUS AND NEXT NODES*/

struct numberNode {
    struct number number;          //name stuct call

    struct numberNode *pNext;    //pointer to next node
    struct numberNode *pPrev;    //pointer to previous node

};

/*THESE NAMENODES WILL BE USED THROUGHOUT THE PRGRAM AS THE HEAD AND TAIL OF THE PROGRAM*/
struct numberNode *pHead = NULL, *pTail=NULL;



/*THIS PROGRAM READS A FILE AND PLACES THE NAMES INTO LINKED LIST*/
void insert_end(int *num)

{

    struct numberNode *var = NULL,*temp = NULL;                   //set temp nodes

    var=(struct numberNode *)malloc(sizeof(struct numberNode));     //allocate memory for new node

    var->number.number= num;                         //set number of number stored in node





    if(pHead==NULL){                                            //check if it is the head


        pHead=var;                                              //set node to head b/c of first element

        pHead->pPrev=NULL;                                      //set node next and prev to null

        pHead->pNext=NULL;

        pTail=pHead;                                            //make head and tail the same

    }else{

        pTail=pHead;                                        //set tail to head

        while(pTail!=NULL)                                  //while tail is not NULL

        {

            temp=pTail;                                     //set temp node to tail pointer

            pTail=pTail->pNext;                             //traverse the linked list

        }

        pTail=var;                                          //set ptail to correct node

        temp->pNext=pTail;                                  //set the temps next to tail

        pTail->pPrev=temp;                                  //set the tail's previous pointer to temp

        pTail->pNext=NULL;                                  //set tail next to NULL

    }


}



/*FUNCTION FOR DISPLAYING LINKED LIST DATA*/
void display(){
    struct numberNode *node;
    node=pHead;
    printf("Displaying Linked List \n ************************************** \n");
    while(node != NULL){
        printf("Number is %d\n", *node->number.number);
        node = node->pNext;
    }
    printf("List is terminated\n ************************************* \n");
}

void displayBackwards(){
    struct numberNode *node;
    node=pTail;
    printf("Displaying Linked List Backwards \n ************************************** \n");
    while(node != NULL){
        printf("Number is %d\n", *node->number.number);
        node = node->pPrev;
    }
    printf("List is terminated\n ************************************* \n");
}




/*DELETE NODE PASSED IN ARGUEMENT*/
void deleteNode(struct numberNode *node){
    if (node!= pHead){
        node->pPrev->pNext=node->pNext;
        node->pNext->pPrev=node->pPrev;
        node->pNext = NULL;
        free(node);
    }else{
        pHead->pNext = pHead;
        free(node);
    }
}

//SWITCH THE LOCATIONS OF THE TWO NODES PASSED AS ARGUEMENTS
void switchNodes(struct numberNode *leftNode, struct numberNode *rightNode){
    struct numberNode temp;
    temp = *leftNode;
    leftNode->number=rightNode->number;
    rightNode->number= temp.number;

}

/*ORGANIZE LINKED LIST IN ALPHABETICAL ORDER*/
void organizeInAscendingOrder(){
    struct numberNode *node = pHead;
    int length=0;
    while(node != NULL){
        node = node->pNext;
        length ++;
    }
    node = pHead;
    int index = 0, secondIndex = 0;
    for (index=0; index<length; index++){
        for (secondIndex=0; secondIndex<length-1; secondIndex++){
            if(node->number.number > node->pNext->number.number){
                switchNodes(node, node->pNext);
            }
            node=node->pNext;
        }
        node=pHead;
    }
}

/*PUSH NODE PASSED AS ARGUEMENT TO THE BACK*/
void pushToBack(struct numberNode *node){
    pTail->pNext = node;
    deleteNode(node);
}


int main() {


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


    int number;

    char *buffer;



    while(fscanf(in_file,"%d", &number)!=EOF)

    {

        insert_end(&number);
    }

    display();

    organizeInAscendingOrder();

    display();

    displayBackwards();


}
#包括
#包括
#包括
/*这是基本的名称结构。它包含名字和姓氏变量*/
结构编号{
int*number;//number
};
/*这是基本的名称节点结构。它包含一个名为STRUCT的结构,以及上一个和下一个节点的结构NAMENODES*/
结构编号节点{
结构编号;//名称结构调用
struct numberNode*pNext;//指向下一个节点的指针
struct numberNode*pPrev;//指向上一个节点的指针
};
/*这些名称节点将在整个程序中用作程序的开头和结尾*/
结构numberNode*pHead=NULL,*pTail=NULL;
/*该程序读取一个文件,并将名称放入链表中*/
无效插入\u结束(int*num)
{
struct numberNode*var=NULL,*temp=NULL;//设置临时节点
var=(struct numberNode*)malloc(sizeof(struct numberNode));//为新节点分配内存
var->number.number=num;//设置存储在节点中的编号
如果(pHead==NULL){//检查它是否是头
pHead=var;//将节点设置为第一个元素的头b/c
pHead->pPrev=NULL;//将node next和prev设置为NULL
pHead->pNext=NULL;
pTail=pHead;//使头部和尾部相同
}否则{
pTail=pHead;//将tail设置为head
while(pTail!=NULL)//while tail不为NULL
{
temp=pTail;//将temp节点设置为尾部指针
pTail=pTail->pNext;//遍历链表
}
pTail=var;//将pTail设置为正确的节点
temp->pNext=pTail;//设置tail旁边的temp
pTail->pPrev=temp;//将尾部的上一个指针设置为temp
pTail->pNext=NULL;//将tail设置为NULL旁边
}
}
/*用于显示链接列表数据的函数*/
无效显示(){
结构编号节点*节点;
node=pHead;
printf(“显示链接列表\n******************************************\n”);
while(节点!=NULL){
printf(“编号为%d\n”,*节点->编号.Number);
node=node->pNext;
}
printf(“列表已终止\n******************************************\n”);
}
void displayBackwards(){
结构编号节点*节点;
node=pTail;
printf(“向后显示链接列表\n***************************************\n”);
while(节点!=NULL){
printf(“编号为%d\n”,*节点->编号.Number);
节点=节点->pPrev;
}
printf(“列表已终止\n******************************************\n”);
}
/*删除参数中传递的节点*/
void deleteNode(结构编号节点*node){
if(节点!=pHead){
节点->pPrev->pNext=节点->pNext;
节点->pNext->pPrev=节点->pPrev;
node->pNext=NULL;
自由(节点);
}否则{
pHead->pNext=pHead;
自由(节点);
}
}
//切换作为参数传递的两个节点的位置
void开关节点(结构编号节点*左节点,结构编号节点*右节点){
结构编号节点温度;
temp=*leftNode;
左节点->编号=右节点->编号;
右节点->编号=临时编号;
}
/*按字母顺序组织链接列表*/
void organizeInAscendingOrder(){
结构编号节点*节点=pHead;
整数长度=0;
while(节点!=NULL){
node=node->pNext;
长度++;
}
node=pHead;
int-index=0,secondIndex=0;
对于(索引=0;索引节点->pNext->number.number){
切换节点(节点,节点->pNext);
}
node=node->pNext;
}
node=pHead;
}
}
/*将节点作为参数传递到后面*/
void pushToBack(结构编号节点*node){
pTail->pNext=节点;
删除节点(node);
}
int main(){
字符文件[100];
printf(“输入文件”);
scanf(“%s”,文件);
文件*in_FILE=fopen(文件“r”);
整数;
字符*缓冲区;
while(fscanf(在_文件中,“%d”和编号)!=EOF)
{
插入\u结束(&编号);
}
显示();
organizeInAscendingOrder();
显示();
向后显示();
}

您的数据结构有点混乱-您可以减少这一点:

struct number {
    int * number;          //number
};
/*THIS IS THE BASIC NAME NODE STRUCTURE. IT CONTAINS A NAME STRUCT AS WELL AS STRUCT NAMENODES TO PREVIOUS AND NEXT NODES*/

struct numberNode {
    struct number number;          //name stuct call

    struct numberNode *pNext;    //pointer to next node
    struct numberNode *pPrev;    //pointer to previous node

};
为此:

struct numberNode {
    int number;                  //number
    struct numberNode *pNext;    //pointer to next node
    struct numberNode *pPrev;    //pointer to previous node

};

i、 e.您不需要多个
struct

不确定为什么要遍历该列表,因为它是双链接的。 这应该起作用:

if (pHead==NULL){
    (...)
} else {
    pHead->pPrev = var;
    pTail->pNext = var;
    var->pPrev = pTail;
    var->pNext = pPrev;
    pTail = var;
}

正如Paul所说,您不一定同时需要这两个struct,但真正的问题是,当您从文件中读取int时,存储在变量“int number;”中,并且每次调用函数insert_end(&number);发送变量编号的地址,但在insert_end函数中,将新节点中新编号的值指定给编号的地址: var->number.number=num;。因此,在您的列表中,numberNode中的所有数字元素都将指向相同的地址

快速修复方法是为文件中读取的每个整数分配新的内存空间。 例:

您还可以按照Paul的建议从结构中删除指针:

struct numberNode {
    int number;                  //number
    struct numberNode *pNext;    //pointer to next node
    struct numberNode *pPrev;    //pointer to previous node
 };
希望有帮助

[编辑]:+1对于提出更好的尾部管理方法的fhsilva,头部应始终指向列表的第一个元素,尾部应始终指向最后一个元素。这样,您就不必通过inse的列表了解新知识
struct numberNode {
    int number;                  //number
    struct numberNode *pNext;    //pointer to next node
    struct numberNode *pPrev;    //pointer to previous node
 };