C 从列表中删除值
我正在写一个程序,它创建列表,打印它,并从列表中删除(3个函数) 打印和回推都很好,它们工作得很好,但我不知道如何在removeFromList()函数中提取要从列表中删除的数字 不要注意名称(比如客户机、套接字),我的客户机服务器应用程序需要保存活动套接字(这就是为什么当客户机断开连接时,我需要将它们从列表中删除) 这里我有两个结构:listElement和clientList(其中包含指向listElement的head元素的指针) 我的后推功能:C 从列表中删除值,c,list,pointers,singly-linked-list,C,List,Pointers,Singly Linked List,我正在写一个程序,它创建列表,打印它,并从列表中删除(3个函数) 打印和回推都很好,它们工作得很好,但我不知道如何在removeFromList()函数中提取要从列表中删除的数字 不要注意名称(比如客户机、套接字),我的客户机服务器应用程序需要保存活动套接字(这就是为什么当客户机断开连接时,我需要将它们从列表中删除) 这里我有两个结构:listElement和clientList(其中包含指向listElement的head元素的指针) 我的后推功能: int pushBackСlient(st
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)。这是无用的。它只会运行一次代码。非常感谢,它工作得非常好。昨天我写了几乎相同的函数,它也可以工作。谢谢你关注我的问题:)非常感谢,它非常有效。昨天我写了几乎相同的函数,它也可以工作。感谢您关注我的问题:)