在结构中存储数据(链表)
Storing data inside structs (Linked List)
大家好,我正在学习C,有些问题我无法解决。
首先,这是我的数据结构:
struct user_node {
void *name;
struct user_node *next;
struct msg_node *msgnext;
};
struct msg_node {
void *sender;
void *receiver;
void *title;
void *content;
struct msg_node *msgnext;
};
struct user_node *user_database = NULL;
这个想法是一个用户可能有一条或多条消息。
我可以创建和删除用户,但我在存储消息时遇到问题,例如:
此函数的目的是将 temp 作为一条消息放入我的数据结构中,供我们在消息本身中找到的给定用户使用。 (温度已经 msg_node 我从另一个函数中获取的数据)
void sendMsg(struct msg_node* temp) {
//if list is empty
if (user_database == NULL) {
printf("There aren't users on the system.\n\n");
return;
}
struct user_node** ptr = &user_database;
while (*ptr) {
if (strncmp((*ptr)->name, (temp)->receiver, strlen(temp-
>receiver)) == 0) {
temp->msgnext = &user_database->msgnext;
user_database->msgnext = temp;
return;
}
ptr = &(*ptr)->next;
}
printf("User not found on the system\n\n");
return;
}
我知道代码有误,但我从昨天开始就一直在弄乱这个,我想不通,有人可以帮我吗?
提前致谢
您可以通过将新节点的 next 指针设置为链表的头部,然后将 lis 的头部设置为新节点来在链表的前面插入一个节点。这甚至适用于空列表,当列表的头部是 NULL
.
时
你几乎说对了,但是列表的头部是与当前用户关联的,而不是与用户列表的头部相关联的,即数据库中的第一个用户。
下面的代码应该可以满足您的需求:
int sendMsg(struct msg_node *msg)
{
struct user_node *user = user_database;
if (user == NULL) {
printf("There aren't users on the system.\n");
return -1;
}
while (user) {
if (strcmp(ptr->name, msg->receiver) == 0) {
msg->msgnext = user->msgnext;
user->msgnext = msg;
return 0;
}
user = user->next;
}
printf("User '%s' not found on the system.\n", msg->receiver);
return -1;
}
备注:
- 我已将指针从相当不起眼的
temp
和 ptr
重命名为更具描述性的 msg
和 user
。
- 我已将函数 return 设为成功代码:0 表示成功,-1 表示失败。
strncmp
将只比较一定数量的字符。我已将其更改为 strcmp
,因此用户 Paul 和 Pauline 被视为不同。
- 没有必要将遍历指针设为指向节点的指针。该技术很有用,但仅在您要插入或删除节点时有用。在前面插入是一种特殊情况,您不需要它。 (而且你插入了一条消息,而不是用户,所以如果你想在其他地方而不是前面插入消息,你可以使用指向消息节点的指针遍历子列表。)
大家好,我正在学习C,有些问题我无法解决。
首先,这是我的数据结构:
struct user_node {
void *name;
struct user_node *next;
struct msg_node *msgnext;
};
struct msg_node {
void *sender;
void *receiver;
void *title;
void *content;
struct msg_node *msgnext;
};
struct user_node *user_database = NULL;
这个想法是一个用户可能有一条或多条消息。
我可以创建和删除用户,但我在存储消息时遇到问题,例如:
此函数的目的是将 temp 作为一条消息放入我的数据结构中,供我们在消息本身中找到的给定用户使用。 (温度已经 msg_node 我从另一个函数中获取的数据)
void sendMsg(struct msg_node* temp) {
//if list is empty
if (user_database == NULL) {
printf("There aren't users on the system.\n\n");
return;
}
struct user_node** ptr = &user_database;
while (*ptr) {
if (strncmp((*ptr)->name, (temp)->receiver, strlen(temp-
>receiver)) == 0) {
temp->msgnext = &user_database->msgnext;
user_database->msgnext = temp;
return;
}
ptr = &(*ptr)->next;
}
printf("User not found on the system\n\n");
return;
}
我知道代码有误,但我从昨天开始就一直在弄乱这个,我想不通,有人可以帮我吗?
提前致谢
您可以通过将新节点的 next 指针设置为链表的头部,然后将 lis 的头部设置为新节点来在链表的前面插入一个节点。这甚至适用于空列表,当列表的头部是 NULL
.
你几乎说对了,但是列表的头部是与当前用户关联的,而不是与用户列表的头部相关联的,即数据库中的第一个用户。
下面的代码应该可以满足您的需求:
int sendMsg(struct msg_node *msg)
{
struct user_node *user = user_database;
if (user == NULL) {
printf("There aren't users on the system.\n");
return -1;
}
while (user) {
if (strcmp(ptr->name, msg->receiver) == 0) {
msg->msgnext = user->msgnext;
user->msgnext = msg;
return 0;
}
user = user->next;
}
printf("User '%s' not found on the system.\n", msg->receiver);
return -1;
}
备注:
- 我已将指针从相当不起眼的
temp
和ptr
重命名为更具描述性的msg
和user
。 - 我已将函数 return 设为成功代码:0 表示成功,-1 表示失败。
strncmp
将只比较一定数量的字符。我已将其更改为strcmp
,因此用户 Paul 和 Pauline 被视为不同。- 没有必要将遍历指针设为指向节点的指针。该技术很有用,但仅在您要插入或删除节点时有用。在前面插入是一种特殊情况,您不需要它。 (而且你插入了一条消息,而不是用户,所以如果你想在其他地方而不是前面插入消息,你可以使用指向消息节点的指针遍历子列表。)