链表实现栈功能异常排查及输入字母判断需求
C语言链表栈实现问题排查与解决方案
问题概述
用C语言基于链表实现栈时出现以下异常:
- push操作成功信息重复打印
- 指令(如pop、退出)未正确执行
- 无法区分字母与非字母输入,非字母内容未触发对应分支
原代码
#include <stdio.h> #include <stdlib.h> struct node{ char data; struct node *next; }; struct node*head; void push(char x){ if (head == NULL) { head= (struct node*) malloc(sizeof(struct node)); head->data=x; head->next=NULL; printf("additon successful\n"); return ; } struct node *temp = (struct node*) malloc(sizeof(struct node)); temp->next=head; temp->data=x; head=temp; printf("additon successful\n"); return ; } void pop(){ if(head == NULL){ printf("list is empty\n"); return ; } struct node *temp = (struct node*) malloc(sizeof(struct node)); temp=head; head=head->next; free(temp); printf("pop is successful\n"); return ; } void print(){ struct node *temp = (struct node*) malloc(sizeof(struct node)); temp=head; while(temp != NULL){ printf("%c ",temp->data); temp=temp->next; } printf("\nall items printed\n"); return ; } void main() { char n; printf("enter alphabet\n"); while (0!=1){ scanf("%c",&n); if(n != 1 && n!= '`' && n!= 4 ) { push(n);} else if(n == 1) { pop();} else if(n == '`') { print();} else if(n == 4) { printf("\nexiting program"); return ;} else { printf("enter valid argument\n");} } }
当前异常输出
enter alphabet r additon successful // why is this printing twice? additon successful a additon successful additon successful n additon successful additon successful d additon successful additon successful 1 // for 1 code should perform pop operation additon successful additon successful 4 // for 4 function should end additon successful additon successful 456 // i could not figure how to add in if condition that n is aplphabet then execute if statement for such no. like 456 execute else additon successful additon successful additon successful //why so many executions? additon successful
预期输出
1 list is empty r additon successful e additon successful a additon successful d additon successful 1 pop is successful 1 pop is successful ` a d all items printed 456 enter valid argument 4 exiting program
问题分析与修复点
1. 重复打印push信息的原因
scanf("%c", &n)会读取输入的换行符(\n),每次输入字符后按回车,换行符会被当成下一个输入触发push,导致两次打印。
修复:在%c前添加空格,跳过空白字符(换行、空格等):
scanf(" %c", &n);
2. 指令判断错误
原代码中用n == 1、n == 4是判断ASCII码为1(SOH)、4(EOT)的特殊字符,而输入的'1'、'4'ASCII码是49、52,导致判断失效。
修复:改为判断字符常量:
else if(n == '1') { pop(); } else if(n == '4') { printf("\nexiting program"); return ; }
3. 未区分字母与非字母输入
原代码逻辑是排除几个字符就执行push,未判断输入是否为字母。需添加字母判断分支。
修复:包含<ctype.h>头文件,使用isalpha()函数判断,或直接用ASCII范围判断:
// 方式1:使用isalpha函数(需包含<ctype.h>) if (isalpha(n)) { push(n); } // 方式2:ASCII范围判断 if ((n >= 'A' && n <= 'Z') || (n >= 'a' && n <= 'z')) { push(n); }
4. 内存泄漏问题
pop()和print()函数中不必要的malloc会导致内存泄漏,因为后续直接将指针赋值为head,malloc的内存未释放。
修复:直接定义指针指向head,无需malloc:
// pop函数修改后 void pop(){ if(head == NULL){ printf("list is empty\n"); return ; } struct node *temp = head; // 移除malloc head=head->next; free(temp); printf("pop is successful\n"); return ; } // print函数修改后 void print(){ if (head == NULL) { printf("list is empty\n"); return; } struct node *temp = head; // 移除malloc while(temp != NULL){ printf("%c ",temp->data); temp=temp->next; } printf("\nall items printed\n"); return ; }
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <ctype.h> // 用于isalpha函数 struct node{ char data; struct node *next; }; struct node* head = NULL; // 初始化head为NULL,避免野指针 void push(char x){ if (head == NULL) { head = (struct node*) malloc(sizeof(struct node)); head->data = x; head->next = NULL; printf("additon successful\n"); return ; } struct node *temp = (struct node*) malloc(sizeof(struct node)); temp->next = head; temp->data = x; head = temp; printf("additon successful\n"); return ; } void pop(){ if(head == NULL){ printf("list is empty\n"); return ; } struct node *temp = head; head = head->next; free(temp); printf("pop is successful\n"); return ; } void print(){ if (head == NULL) { printf("list is empty\n"); return; } struct node *temp = head; while(temp != NULL){ printf("%c ", temp->data); temp = temp->next; } printf("\nall items printed\n"); return ; } int main() { // 标准main函数返回int类型 char n; printf("enter alphabet\n"); while (1){ // 简化循环条件 scanf(" %c", &n); // 跳过空白字符 if (isalpha(n)) { push(n); } else if(n == '1') { pop(); } else if(n == '`') { print(); } else if(n == '4') { printf("\nexiting program"); return 0; } else { printf("enter valid argument\n"); } } return 0; }
验证说明
修复后的代码可实现:
- 输入字母时执行push,仅打印一次成功信息
- 输入
'1'执行pop,栈空时提示"list is empty" - 输入非字母(如
456的每个字符)时触发"enter valid argument" - 输入
'4'正常退出程序 - 输入
''`打印栈内元素,栈空时提示对应信息
内容的提问来源于stack exchange,提问作者vatsal
相关产品推荐
相关产品推荐

