Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从列表中删除值_C_List_Pointers_Singly Linked List - Fatal编程技术网

C 从列表中删除值

C 从列表中删除值,c,list,pointers,singly-linked-list,C,List,Pointers,Singly Linked List,我正在写一个程序,它创建列表,打印它,并从列表中删除(3个函数) 打印和回推都很好,它们工作得很好,但我不知道如何在removeFromList()函数中提取要从列表中删除的数字 不要注意名称(比如客户机、套接字),我的客户机服务器应用程序需要保存活动套接字(这就是为什么当客户机断开连接时,我需要将它们从列表中删除) 这里我有两个结构:listElement和clientList(其中包含指向listElement的head元素的指针) 我的后推功能: int pushBackСlient(st

我正在写一个程序,它创建列表,打印它,并从列表中删除(3个函数)

打印和回推都很好,它们工作得很好,但我不知道如何在removeFromList()函数中提取要从列表中删除的数字

不要注意名称(比如客户机、套接字),我的客户机服务器应用程序需要保存活动套接字(这就是为什么当客户机断开连接时,我需要将它们从列表中删除)

这里我有两个结构:listElement和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行,但不确定

更新日期:2017年5月13日

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;    
    }
} 
至于列表结构,我建议使用structs结构,如下所示:

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;

它会让你更好地控制你的列表

对于删除功能,我建议如下:

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;    
    }
} 
至于列表结构,我建议使用structs结构,如下所示:

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;

它会让你更好地控制你的列表

函数
removeFromList
是错误的,至少因为当列表只包含一个元素时,while语句的这个条件可能等于false。在这种情况下,即使这一个元素包含目标vakue,它也不会被删除

while (currentElement != 0 && currentElement->next != 0)
这些功能可以如演示程序所示

#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;
}

您至少需要添加一个函数来释放列表中的所有元素。

函数
removeFromList
是错误的,至少因为当列表只包含一个元素时,while语句的条件可能等于false。在这种情况下,即使这一个元素包含目标vakue,它也不会被删除

while (currentElement != 0 && currentElement->next != 0)
这些功能可以如演示程序所示

#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;
}


您至少需要添加一个函数来释放列表中的所有元素。

您的第一个也是最重要的错误是认为这是C!这是课堂(学习)练习吗?如果不只是使用
std::list
@Olaf,我不明白你为什么这么说。我还使用stdio.h、stdlib.h和winsock2.hlibraries@RichardCritten这是一个测试任务,但我需要它在我的项目清洁C. @乔治Z.在C和C++之间做出选择。如果是C++程序,则使用运算符new代替MALOC。如果它是一个C程序,那么使用free而不是delete。你的第一个也是最重要的错误是认为这是C!这是课堂(学习)练习吗?如果不只是使用
std::list
@Olaf,我不明白你为什么这么说。我还使用stdio.h、stdlib.h和winsock2.hlibraries@RichardCritten这是一个测试任务,但我需要它在我的项目清洁C. @乔治Z.在C和C++之间做出选择。如果是C++程序,则使用运算符new代替MALOC。如果它是一个C程序,那么使用免费而不是删除。谢谢你的建议和你的功能。我对使用我的结构有点(甚至没有一点)困惑,所以现在我想让它保持原状:)谢谢你的帮助。关于remove()函数,我已经编辑了我的问题。我在调试方面遇到了问题。似乎我无法从列表中删除正确的套接字。而且实际上没有得到列表中第一个元素的结果。Thanks@GeorgeZ. 我很高兴能对你有所帮助。你解决你的问题了吗?没有。我做错了,插座仍然无法移除。我在调试模式下进行了检查:它将套接字值获取到currentElement,但随后它被更改为列表中的下一个值,并且没有删除。您知道如何修复我的新函数吗?Dubugging说的是“内存读取错误”。我假设它尝试在free()之后读取内存,但首先没有发现任何内容。您永远不会读取列表中的最后一个元素,因为您的“if”表示您只能分析不是0的元素,并且下一个元素不是0。第二,为什么要使用while(false)。这是无用的。它将只运行一次主体代码。感谢您的建议和您的功能。我对使用我的结构有点(甚至没有一点)困惑,所以现在我想让它保持原状:)谢谢你的帮助。关于remove()函数,我已经编辑了我的问题。我在调试方面遇到了问题。似乎我无法从列表中删除正确的套接字。而且实际上没有得到列表中第一个元素的结果。Thanks@GeorgeZ. 我很高兴能对你有所帮助。你解决你的问题了吗?没有。我做错了,插座仍然无法移除。我在调试模式下进行了检查:它将套接字值获取到currentElement,但随后它被更改为列表中的下一个值,并且没有删除。您知道如何修复我的新函数吗?Dubugging说的是“内存读取错误”。我假设它尝试在free()之后读取内存,但首先没有发现任何内容。您永远不会读取列表中的最后一个元素,因为您的“if”表示您只能分析不是0的元素,并且下一个元素不是0。第二,为什么要使用while(false)。这是无用的。它只会运行一次代码。非常感谢,它工作得非常好。昨天我写了几乎相同的函数,它也可以工作。谢谢你关注我的问题:)非常感谢,它非常有效。昨天我写了几乎相同的函数,它也可以工作。感谢您关注我的问题:)