C语言 构建字符串的链表



我有一个单向链表,它成功地接受了整数,但现在我想使用字符串。但是它不起作用。我收到了很多关于"铸造"的不同错误。我也在网上发现了相互矛盾的信息。这里的一条评论,创建字符串的链表,说不要使用 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 valuechar *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;
}

最新更新