求助:C语言concat_nodes函数无法将链表内容复制到字符数组
问题分析与修正
你的代码里concat_nodes函数及其他部分存在多个逻辑和语法问题,导致无法正确生成目标字符串,下面逐个拆解:
1. 核心逻辑错误:数据复制方向搞反
在concat_nodes里,你写的是node->data = str[counter];——这是把数组内容赋值给节点,完全搞反了!正确逻辑应该是把节点的字符复制到数组:str[counter] = node->data;。
2. 空格处理错误
你直接给str[counter+1]=' ';,不仅索引计算错误,还没考虑最后一个节点不需要加空格的情况。应该只在非最后节点的字符后添加空格,最后一个节点仅写入字符。
3. 字符串未添加终止符
C语言字符串必须以'\0'结尾,否则strcmp、printf("%s")等字符串操作都会出错,你的代码完全没处理这一点。
4. 不必要的scanf调用
main函数里的scanf("%s",alph);完全多余,它会覆盖数组初始值(未初始化时是垃圾值),直接破坏后续填充逻辑,必须删掉。
5. 链表顺序颠倒
你的push函数是头插法,每次新节点加到链表头部。循环从A(65)到Z(90)依次push,最后链表顺序是Z→Y→X→…→A,生成的字符串会是Z Y X ... A,和期望的A B C ... Z相反,需要改成尾插法。
6. 无效代码与断言错误
concat_nodes里的strlen(str) == ((counter1*2)-2);是无意义的比较表达式,没有任何作用,直接删掉。- 断言里的目标字符串末尾多了一个空格:
"...Z ",不符合要求,应该改成"A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"。 make_list函数里的counter1++;在return head;之后,永远不会执行,直接删掉即可。
修正后的完整代码
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <assert.h> // 结构体定义 struct strnode{ struct strnode *front; int data; struct strnode *next; }; void list_destroy(struct strnode *head); // 修改为尾插法,保证链表顺序为A→B→…→Z void push(struct strnode *head, char value); void concat_nodes(struct strnode *head, char *str); // 记录链表长度的计数器 int counter1 = 0; struct strnode *make_list(); int main(){ struct strnode *head = make_list(); // 循环添加A到Z到链表 for(int i=65; i<=90; i++){ push(head, i); counter1++; } // 数组长度:26个字符 + 25个空格 + 1个终止符 = 52 char alph[(counter1 * 2) - 1 + 1]; concat_nodes(head, alph); // 直接打印字符串更简洁 printf("%s\n", alph); // 修正断言的目标字符串,去掉末尾空格 assert(strcmp(alph,"A B C D E F G H I J K L M N O P Q R S T U V W X Y Z")==0); list_destroy(head); return 0; } // 创建链表头节点 struct strnode *make_list(){ struct strnode *head = malloc(sizeof(struct strnode)); head->front = NULL; return head; } // 尾插法添加节点,保证顺序正确 void push(struct strnode *head, char value){ struct strnode *new_node = malloc(sizeof(struct strnode)); new_node->data = value; new_node->next = NULL; if(head->front == NULL){ // 链表为空,新节点作为第一个节点 head->front = new_node; } else { // 找到链表尾部 struct strnode *curr = head->front; while(curr->next != NULL){ curr = curr->next; } curr->next = new_node; } } // 将链表转换为目标字符串 void concat_nodes(struct strnode *head, char *str){ struct strnode *node = head->front; int counter = 0; while(node){ // 将节点字符复制到数组 str[counter] = node->data; counter++; // 如果不是最后一个节点,添加空格 if(node->next != NULL){ str[counter] = ' '; counter++; } node = node->next; } // 添加字符串终止符 str[counter] = '\0'; } // 销毁链表 void list_destroy(struct strnode *head){ struct strnode *curnode = head->front; struct strnode *nextnode = NULL; while(curnode){ nextnode = curnode->next; free(curnode); curnode = nextnode; } free(head); }
关键修正说明
- 尾插法push:修改push函数为尾插,保证链表顺序是A到Z,生成的字符串顺序正确。
- 数组长度调整:考虑字符串终止符,数组长度设为52(26字符+25空格+1终止符)。
- concat_nodes逻辑修正:
- 正确复制节点数据到数组
- 仅在非最后节点后添加空格
- 添加字符串终止符
- 移除无效代码:删掉多余的scanf和无意义的比较表达式
- 修正断言字符串:去掉末尾空格,保证断言逻辑正确
内容的提问来源于stack exchange,提问作者Ali Ghosn
相关产品推荐
相关产品推荐

