2017-05-12 2 views
1

목록을 작성하고 인쇄하고 목록에서 제거하는 프로그램을 작성 중입니다 (3 함수).목록에서 값을 제거하십시오.

인쇄 및 푸시 백은 훌륭하지만 잘 작동하지만 removeFromList() 함수에서 목록에서 제거 할 숫자를 선택하는 방법을 알 수 없습니다.

이름 (클라이언트, 소켓 등)에주의하지 마십시오. 내 클라이언트 - 서버 응용 프로그램이 활성 소켓을 저장하기 때문에 클라이언트가 연결이 끊어지면 목록에서 제거해야합니다. listElement 및 clientList

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

struct clientList 
{ 
    listElement * head; 
}; 

내 푸시 백 기능 (listElement의 요소 머리에 대한 포인터를 포함합니다) :

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; 
    } 
} 
을 여기

나는 2 개 구조를 가지고

그리고 문제가 있습니다 (소켓이 추가되었는지 확인하기 위해 디버그 메시지를 만들었습니다. 바르게). 처음 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); 
} 

감사합니다. 다음과 같은

목록 구조로
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

가장 중요한 오류는 이것이 C라고 생각하는 것입니다. – Olaf

+1

수업 (학습) 연습입니까? 그냥'std :: list'를 사용하지 않는다면. –

+0

@Olaf 왜 그런 말을하는지 이해하지 못했습니다. 또한 stdio.h, stdlib.h 및 winsock2.h 라이브러리를 사용하고 있습니다. –

답변

4

함수 removeFromList은 목록에 요소가 하나만있는 경우 while 문이이 조건이 false 일 수 있기 때문에 잘못되었습니다. 이 경우에도이 하나의 요소는 제거 대상이 아닌 대상을 포함합니다.

기능은 시범 프로그램에 표시되어있는 것처럼 보일 수 있습니다.

#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

나는이 같은 제안 귀하의 목록을보다 잘 관리하십시오.

+0

제안 및 귀하의 기능에 감사드립니다. 나는 조금이라도 (심지어는 조금도 아님) 사용하는 구조를 혼란스럽게 만들었으니 지금 나는 그 상태로두고 싶다. :) 나는 당신의 도움을 갚는다. remove() 함수는 - 내 질문을 편집했습니다. 디버깅에 문제가 있습니다. 그것은 내가 목록에서 제거하고자하는 올바른 소켓을 얻을 수없는 것 같습니다. 실제로 목록의 첫 번째 요소를 가져올 항목을 얻지 못했습니다. 감사합니다 –

+0

@ 조지 츠. 나는 유용하게되어서 기쁩니다. 문제를 해결 했습니까? –

+0

아닙니다. 내가 잘못 했어, 소켓은 여전히 ​​제거 할 수 없다. 디버그 모드에서 체크 : 그것은 currentElement에 소켓 값을 가져 오지만 목록의 다음 값으로 변경되고 제거되지는 않습니다. –

관련 문제