1

C で簡単なテキスト エディターをプログラムしようとしており、LinkedList を使用しています。deleteEnd 関数に問題があります。どこで私は間違えましたか?

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

キャラクターとキャラクターの座標を次のような構造に保存します。

struct node {
    struct node *previous;
    char c;
    int x;
    int y;
    struct node *next;
}*head;

これは、文字が入力されるたびに呼び出されます。

void characters(char typed, int xpos, int ypos)     //assign values of a node
{
    struct node *temp,*var,*temp2;
    temp=(struct node *)malloc(sizeof(struct node));
    temp->c=typed;
    temp->x=xpos;
    temp->y=ypos;

    if(head==NULL)
    {
        head=temp;
        head->next=NULL;
    }

    else
    {
        temp2=head;
        while(temp2!=NULL)
        {
            var=temp2;
            temp2=temp2->next;
        }
        temp2=temp;
        var->next=temp2;
        temp2->next=NULL;
    }
}

変更がある場合は、新しいノードを出力します。

void printer()          //to print everything
{
    struct node *temp;
    temp=head;
    while(temp!=NULL)
    {
        gotoxy(temp->x,temp->y);
        printf("%c",temp->c);
        temp=temp->next;
    }

}

ここで、頭の最後の要素が削除されない理由がわかりません。

void deletesEnd()
{
    struct node *temp,*last;
    temp=head;
    while(temp!=NULL)
    {
        last=temp;
        temp=temp->next;
    }
    if(last->previous== NULL)
    {
        free(temp);
        head=NULL;
    }
    last=NULL;
    temp->previous=last;
    free(temp);
}

ここからすべてが始まります。

main()
{
    char c;         //for storing the character
    int x,y;        //for the position of the character
    clrscr();
    for(;;)
    {
        c=getch();
        x=wherex();
        y=wherey();
        if(c==0x1b)     //escape for exit
        {
            exit(0);
        }

        else if (c==8)  //for backspace
        {
            deletesEnd();
            // clrscr();
            printer();
        }

        else            //normal characters
        {
            characters(c,x,y);
            printer();
        } 

    }
}
4

5 に答える 5

1

nextリスト内の最後のノードを見つけるための最も簡単な方法は、ポインターがになるまでループすることですNULL

最後に削除するには、最後から 2 番目のノードも追跡する必要があり、次のようになります。

struct node *prev, *curr;

for (prev = NULL, curr = head; curr->next != NULL; prev = curr, curr = curr->next)
    ;

/* `curr` is now the last node in the list, `prev` is the next-to-last node */
if (prev != NULL)
    prev->next = NULL;  /* Unlink the last node */
else
    head = NULL;  /* List was only one node long */

/* Free the memory for the last node */
free(curr);

リストを適切に二重リンクしたままにしておくと、最後から 2 番目のノードを追跡する必要がなくなるため、ループはさらに簡単になります。

struct node *node;

for (node = head; node->next != NULL; node = node->next)
    ;

/* `node` is now the last node in the list */
if (node->previous != NULL)
    node->previous->next = NULL;  /* Unlink last node */
else
    head = NULL;  /* List was only one node long */

/* Free the memory for the last node */
free(curr);

最初からテールを追跡しておくと、これがはるかに簡単になります。

if (tail != NULL)
{
    struct node *node = tail;

    if (node->previous != NULL)
    {
        node->previous->next = NULL;  /* Unlink last node */
        tail = node->previous;
    }
    else
        head = tail = NULL;  /* Removing last node in list */

    free(node);
}
于 2013-07-31T10:38:12.720 に答える
1

これを試して :

void deletesEnd()
{
struct node *temp,*last;
temp=head;
last = temp;
while(temp != NULL && temp->next!=NULL)
{
    last=temp;
    temp=temp->next;
}
if(last == temp)
{
    free(temp);
    head=NULL;
} else {
    free(last->next);
    last->next = NULL;
}

あなたのアルゴリズムでは、NULL ポインターを操作しようとしているため、前のノードに到達できないと思います。

于 2013-07-31T10:38:30.157 に答える
0

これを試して

void deletesEnd()
{
   struct node *temp,*last;
   temp=head;

   while(temp!=NULL)
   {
       last=temp;
       temp=temp->next;
   }

   if(last->previous== NULL)
   {
        free(temp);
        head=NULL;
   }

   last->previous->next = NULL;
   last=NULL;
   temp->previous=last;
   free(temp);
}

ご覧のとおり、リストの最後の要素を に配置してから、lastnulllast=NULL;last変数に配置しました。tempもうNULLそうtemp->previous=last;で意味がありません。NULL最後のアイテムの前のアイテムが行として指す必要があります

last->previous->next = NULL;

する

于 2013-07-31T10:37:21.137 に答える
0

この行:

temp->previous=last;

temp はその時点で既に null であるため (while ループの終了条件であるため)、問題が発生します。

メソッドを次のように変更します。

void deletesEnd()
{
   struct node *temp,*last;
   temp=head;
   while(temp!=NULL)
   {
       last=temp;
       temp=temp->next;
   }
   if(last != NULL) {
       if (last->previous != null) { // Last element gonig to be deleted so the previous element if exists should point his next to null (end of list)       
           last->previous->next = null;
       }   
       free(last); // Free the last element in the list
   }
}
于 2013-07-31T10:37:48.350 に答える