我有一个单向链表,它成功地接受了整数,但现在我想使用字符串。但是它不起作用。我收到了很多关于"铸造"的不同错误。我也在网上发现了相互矛盾的信息。这里的一条评论,创建字符串的链表,说不要使用 strcpy,但我看到 strcpy 在网上的一些例子中使用。
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
struct node {
char value[];
struct node* next; // pointer of structure type
};
// set existing type, node, to the alias, node_t
typedef struct node node_t;
node_t *create_new_node(char value) {
// create space for node with malloc
node_t *result = malloc(sizeof(node_t));
// set the value of the new node
result->value = value;
//strcpy(result->value, value);
// set the value's next pointer to null
result->next = NULL;
return result;
}
node_t *insert_at_head(node_t **head, node_t *node_to_insert) {
node_to_insert->next = *head;
*head = node_to_insert;
return node_to_insert;
}
//Prints linked list
void printlist(node_t* head) {
node_t *temporary = head;
while (temporary != NULL) {
//print out the value of the node that temporary points to
// printf("%d - ", temporary->value);
// to move along the list
temporary = temporary->next;
}
printf("n");
}
int main() {
node_t *tmp;
// declaring head pointer
node_t *head = NULL;
// CREATING LINKED LIST
// for (int i = 0; i < 25; i++) {
// tmp = create_new_node(i);
// // sending the address of the head variable
// //calling by reference
// //SINCE HEAD IS ALREADY A NODE POINTER
// insert_at_head(&head, tmp);
// }
printlist(head);
tmp = create_new_node("I like food");
insert_at_head(&head, tmp);
}
如何让这个字符串链表工作? 谢谢。
请使用您的编译器!我在这段代码上运行了$gcc -Wall a.c
并得到:
a.c:7:10: error: flexible array member not at end of struct
char value[];
^
a.c: In function ‘main’:
a.c:67:5: warning: passing argument 1 of ‘create_new_node’ makes integer from pointer without a cast [enabled by default]
tmp = create_new_node("I like food");
^
a.c:15:9: note: expected ‘char’ but argument is of type ‘char *’
node_t *create_new_node(char value) {
^
a.c:70:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
现在我们知道问题是什么了。首先,char value[]
应该是char *value
的,因为它是一个指针而不是一个灵活的数组成员(FAM(。如果需要,您还可以将 FAM 移动到结构的末尾,如下所示。
接下来,当您真正想要一个字符串时,node_t *create_new_node(char value)
依赖于char value
,char *value
参数。除此之外还有问题:您可能希望为节点创建字符串的副本,以防它从堆栈中消失。此内存应在使用后清理。
其他提示:
避免嘈杂、多余的评论,例如:
// declaring head pointer node_t *head = NULL;
malloc(sizeof(*name_of_the_var));
比malloc(sizeof(node_t));
数据更改更安全。node_t *insert_at_head(node_t **head, node_t *node_to_insert)
修改其参数并返回它有点不寻常。我会使就地合同明确void
。按字母顺序排列并删除未使用的导入。
检查
malloc
调用是否成功。记得从主
return 0;
。typedef struct node node_t;
还可以,但也隐藏了信息 - 我更喜欢将struct
保留在那里。
下面是可能的重写:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char *value;
struct node* next;
};
struct node *create_new_node(char *value) {
struct node *node = malloc(sizeof(*node));
if (!node) {
fprintf(stderr, "%s:%d malloc failedn", __FILE__, __LINE__);
exit(1);
}
node->next = NULL;
node->value = strdup(value);
if (!node->value) {
fprintf(stderr, "%s:%d malloc failedn", __FILE__, __LINE__);
exit(1);
}
return node;
}
void insert_at_head(struct node **head, struct node *node_to_insert) {
node_to_insert->next = *head;
*head = node_to_insert;
}
void print_list(struct node *head) {
for (; head; head = head->next) {
printf("%s->", head->value);
}
puts("");
}
void free_list(struct node *head) {
while (head) {
struct node *tmp = head;
head = head->next;
free(tmp->value);
free(tmp);
}
}
int main() {
struct node *head = NULL;
for (int i = 0; i < 10; i++) {
char n[16];
sprintf(n, "%d", i);
insert_at_head(&head, create_new_node(n));
}
print_list(head);
free_list(head);
return 0;
}
输出:
9->8->7->6->5->4->3->2->1->0->
如果你稍微重新组织一下,你将能够在单个malloc中分配结构的空间和字符串的位置。
struct node
{
struct node* next; // pointer of structure type
char value[];
};
// set existing type, node, to the alias, node_t
typedef struct node node_t;
node_t *create_new_node(const char *value)
{
// create space for node with malloc
node_t *result = malloc(sizeof(*result) + strlen(value) + 1);
if(result)
{
strcpy(result->value, value);
result->next = NULL;
}
return result;
}