2017-05-12 13 views
1

リストを作成し、それを印刷してリストから削除するプログラムを作成しています(3つの関数)。リストから値を削除する

プリントとプッシュバックはうまくいきますが、うまく機能しますが、removeFromList()関数のリストから削除する数値を選択する方法を理解できません。

名前(クライアント、ソケットなど)に注意を払わないでください。クライアント/サーバアプリケーションがアクティブソケットを保存するためです(クライアントが切断されたときにリストから削除する必要があります)。

ここで私は2つの構造を有する:listElementとclientList(listElementの要素を先頭へのポインタが含まれています)

struct listElement 
{ 
    SOCKET socket; 
    struct listElement* next; 
}; 

struct clientList 
{ 
    listElement * head; 
}; 

マイプッシュバック機能:

int pushBackСlient(struct clientList* list, int socket) 
{ 
    struct listElement* newClient = (struct listElement*)malloc(sizeof(struct listElement)); 
    struct listElement* currentElement = list->head; 
    newClient->socket = socket; 
    newClient->next = 0; 
    do 
    { 
     // IT'S PUSHBACK 
     if (list->head == 0) 
     { 
      list->head = newClient; 
      break; 
     } 
     while (currentElement->next != 0) 
     { 
      currentElement = currentElement->next; 
     } 
     currentElement->next = newClient; 
    } while (false); 

    return 0; 
} 

マイプリント:

void print(struct clientList* list) 
{ 
    struct listElement* currentElement = list->head; 
    while (currentElement != 0) 
    { 
     printf("%d\n", currentElement->socket); 
     currentElement = currentElement->next; 
    } 
} 

機能に問題があります(「ソケット」が追加されたかどうかを確認するためにデバッグメッセージを作成しました)正しく)。最初の3行は必要ないとは思いますが、わかりません。

更新 13/05/2017

void removeFromList(struct clientList* list, int socket) 
{ 
    struct listElement* currentElement = list->head; 
    do 
    { 
     if (list->head == 0) 
     { 
      return; 
     } 

     while (currentElement != 0 && currentElement->next != 0) 
     { 
      if (currentElement->socket == socket) 
      { 
       printf("currentElement == %d\n", currentElement); 
       currentElement = currentElement->next; 
       printf("currentElement == %d\n", currentElement); 
       free(currentElement); 
       //break; // if I only want to remove the first socket? 
      } 
      currentElement = currentElement->next; 
     } 
    } while (false); 
} 

ありがとうございました。あなたのremove関数の場合

+0

あなたの最初の最も重要なエラーは、これがCだと思っていることです! – Olaf

+1

これはクラス(学習)練習ですか?単に 'std :: list'を使用しない場合。 –

+0

@Olafなぜあなたはそれを伝えているのか分かりませんでした。またstdio.h、stdlib.h、winsock2.hライブラリを使用しています –

答えて

4

関数removeFromListが間違っているのは、リストに要素が1つしか含まれていない場合、while文のこの条件がfalseになる可能性があるからです。この場合、この1つの要素でさえもターゲットの塊が含まれているため、削除されません。

機能は、デモンストレーションプログラムに表示されているように見えます。

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

typedef int SOCKET; 

struct listElement 
{ 
    SOCKET socket; 
    struct listElement *next; 
}; 

struct clientList 
{ 
    struct listElement *head; 
}; 

int pushBackClient(struct clientList *list, SOCKET socket) 
{ 
    struct listElement *newClient = malloc(sizeof(struct listElement)); 
    int success = newClient!= NULL; 

    if (success) 
    { 
     newClient->socket = socket; 
     newClient->next = NULL; 

     struct listElement **current = &list->head; 

     while (*current != NULL) current = &(*current)->next; 

     *current = newClient; 
    } 

    return success; 
} 


int removeFromList(struct clientList *list, SOCKET socket) 
{ 
    int success; 

    struct listElement **current = &list->head; 

    while (*current != NULL && (*current)->socket != socket) 
    { 
     current = &(*current)->next; 
    } 

    if ((success = *current != NULL)) 
    { 
     struct listElement *tmp = *current; 
     *current = (*current)->next; 

     free(tmp); 
    } 

    return success; 
} 

void print(struct clientList *list) 
{ 
    for (struct listElement *current = list->head; 
      current != NULL; 
      current = current->next) 
    {   
     printf("%d ", current->socket); 
    } 
} 

int main(void) 
{ 
    const int N = 10; 
    struct clientList list = { NULL }; 

    for (int i = 0; i < N; i++) pushBackClient(&list, i); 

    print(&list); 
    putchar('\n'); 

    for (int i = 0; i < N; i++) 
    { 
     if (i % 2 == 0) removeFromList(&list, i); 
    } 

    print(&list); 
    putchar('\n'); 

    for (int i = 0; i < N; i++) 
    { 
     if (i % 2 == 1) removeFromList(&list, i); 
    } 

    print(&list); 
    putchar('\n'); 

    return 0; 
} 

プログラムの出力は、あなたが、少なくとも、リストのすべての要素を解放する機能を追加する必要が

0 1 2 3 4 5 6 7 8 9 
1 3 5 7 9 

です。

+0

ありがとう、それは完全に動作します。昨日私はほぼ同じ機能を書いており、それも機能します。私の問題に注意をしていただきありがとうございます:) –

+0

@GeorgeZ。いいえ、まったく。どういたしまして。 –

0

私はこのような何かお勧め:以下のようなあなたのリスト構造については

void removeFromList(struct clientList* list, int socket) 
{ 
    struct listElement* aux, prev; 
    if(list->head == 0) 
     return; 

    aux = list->head; 
    prev = aux; 

    while(aux != 0){ 
     if(aux->socket == socket) { 
      prev->next = aux->next; 
      free(aux); 
      break; // if you only want to remove the first socket 
     } 
     prev = aux; 
     aux = aux->next;  
    } 
} 

を、私は、構造体の構造を使用することをお勧め:

struct list 
{ 
    int numberOfElements; 
    NODE * first; 
} LIST; 

struct node 
{ 
    ELEMENT * info; 
    NODE * prev; // If you want to have a double connection between the nodes 
    NODE * next; 
} NODE; 

struct element 
{ 
    int id; 
    /* Other Properties */ 
} ELEMENT; 

それはあなたを与える必要がありますあなたのリストのより良いコントロール。

+0

提案していただきありがとうございます。私はちょっと(ちょっとではなく)私の構造を使って混乱しているので、私はその状態にしておきたいと思っています:)あなたの助けを惜しみません。 remove()関数に関して - 私は自分の質問を編集しました。私はデバッグに問題があります。それは私がリストから削除したい正しいソケットを得ることができないようだ。そして実際にリストの最初の要素を取り上げるものを実際には得られませんでした。ありがとう –

+0

@ GeorgeZ。私は有用であったことをうれしく思います。あなたはあなたの問題を解決しましたか? –

+0

実際にはありません。私は間違っていた、ソケットはまだ削除することはできません。私はデバッグモードでチェックしました:それはcurrentElementにソケット値を取得しますが、それはリストの次の値に対して変更され、削除されません。 –

関連する問題