从结构数组中删除项目
Remove Items from a struct array
所以我在 C 中实现了一个 TCP 服务器聊天室,并使用轮询来处理多个客户端。用户使用用户名和密码注册,然后使用它登录。当他们登录时,我想将他们添加到这个结构数组中。
struct onlineUsers{
int sockfd;
char username[9]; //usernames size is maximum 8 characters
};
struct onlineUsers users[10];
//The login function is pretty long so is here the relevant part.
if(!searchExist(search, db)){
printf("Account doesnt exist.\n");
fclose(db);
free(search);
return -1;
}
else{
printf("Logged in\n");
// Add to onlineUser struct arr[]
}
但是当客户端关闭连接时,您将如何从 onlineUsers 数组中删除该特定元素?我还没有实现添加它们的方法,因为我真的没有删除它们的好方法。
我将其重新设计为一个最小示例并为您实现了线性搜索(如果可用,请在 remove_user()
中使用 lfind
并在 add_user()
中使用 lsearch
):
#include <assert.h>
#include <string.h>
#define MAX_NAME 8
#define MAX_USERS 2
struct user {
char name[MAX_NAME + 1];
};
unsigned find_pos(struct user *users, const char *name) {
unsigned empty = MAX_USERS;
for(unsigned i = 0; i < MAX_USERS; i++) {
if(empty == MAX_USERS && !users[i].name[0]) empty = i;
if(!strcmp(users[i].name, name)) return i;
}
return empty;
}
int add_user(struct user *users, const char *name) {
unsigned pos = find_pos(users, name);
if(pos == MAX_USERS) return -1;
if(users[pos].name[0]) return 1;
// safe as name[8] is 0 initialized; otherwise
// copy MAX_NAME + 1 then set name[MAX_NAME] = '[=10=]'
// to ensure string is [=10=] terminated.
strncpy(users[pos].name, name, MAX_NAME);
return 0;
}
int remove_user(struct user *users, const char *name) {
int pos = find_pos(users, name);
if(!users[pos].name[0] || strcmp(users[pos].name, name)) return 1;
users[pos].name[0] = '[=10=]';
return 0;
}
int main() {
struct user users[MAX_USERS] = { 0 };
assert(add_user(users, "bob") == 0); // ok (1 of 2)
assert(add_user(users, "bob") == 1); // duplicate
assert(remove_user(users, "bob") == 0); // ok (empty)
assert(remove_user(users, "jane") == 1); // non-existing
assert(add_user(users, "bob") == 0); // ok (1 of 2)
assert(add_user(users, "jane") == 0); // ok (2 of 2)
assert(add_user(users, "jack") == -1); // full
assert(remove_user(users, "bob") == 0); // ok
assert(find_pos(users, "jane") == 1); // ok (not empty slot)
}
所以我在 C 中实现了一个 TCP 服务器聊天室,并使用轮询来处理多个客户端。用户使用用户名和密码注册,然后使用它登录。当他们登录时,我想将他们添加到这个结构数组中。
struct onlineUsers{
int sockfd;
char username[9]; //usernames size is maximum 8 characters
};
struct onlineUsers users[10];
//The login function is pretty long so is here the relevant part.
if(!searchExist(search, db)){
printf("Account doesnt exist.\n");
fclose(db);
free(search);
return -1;
}
else{
printf("Logged in\n");
// Add to onlineUser struct arr[]
}
但是当客户端关闭连接时,您将如何从 onlineUsers 数组中删除该特定元素?我还没有实现添加它们的方法,因为我真的没有删除它们的好方法。
我将其重新设计为一个最小示例并为您实现了线性搜索(如果可用,请在 remove_user()
中使用 lfind
并在 add_user()
中使用 lsearch
):
#include <assert.h>
#include <string.h>
#define MAX_NAME 8
#define MAX_USERS 2
struct user {
char name[MAX_NAME + 1];
};
unsigned find_pos(struct user *users, const char *name) {
unsigned empty = MAX_USERS;
for(unsigned i = 0; i < MAX_USERS; i++) {
if(empty == MAX_USERS && !users[i].name[0]) empty = i;
if(!strcmp(users[i].name, name)) return i;
}
return empty;
}
int add_user(struct user *users, const char *name) {
unsigned pos = find_pos(users, name);
if(pos == MAX_USERS) return -1;
if(users[pos].name[0]) return 1;
// safe as name[8] is 0 initialized; otherwise
// copy MAX_NAME + 1 then set name[MAX_NAME] = '[=10=]'
// to ensure string is [=10=] terminated.
strncpy(users[pos].name, name, MAX_NAME);
return 0;
}
int remove_user(struct user *users, const char *name) {
int pos = find_pos(users, name);
if(!users[pos].name[0] || strcmp(users[pos].name, name)) return 1;
users[pos].name[0] = '[=10=]';
return 0;
}
int main() {
struct user users[MAX_USERS] = { 0 };
assert(add_user(users, "bob") == 0); // ok (1 of 2)
assert(add_user(users, "bob") == 1); // duplicate
assert(remove_user(users, "bob") == 0); // ok (empty)
assert(remove_user(users, "jane") == 1); // non-existing
assert(add_user(users, "bob") == 0); // ok (1 of 2)
assert(add_user(users, "jane") == 0); // ok (2 of 2)
assert(add_user(users, "jack") == -1); // full
assert(remove_user(users, "bob") == 0); // ok
assert(find_pos(users, "jane") == 1); // ok (not empty slot)
}