使用3个函数实现回文判断时程序抛出异常求解决
C语言回文判断程序异常排查与修复
常见异常原因及修复点
1. 只读字符串修改触发未定义行为
若直接传入字符串字面量(如char *str = "A man, a plan, a canal: Panama";)给checker或lowerCase函数修改,会触发段错误——因为字符串字面量存储在只读内存区,不允许修改。修复方式是将字面量复制到可写字符数组中。
2. checker函数未处理字符串结束符
移除非字母字符时,若忘记在新字符串末尾添加'\0',后续函数处理会因读取越界抛出异常。
3. 内存分配/释放问题
checker函数若动态分配内存存储过滤后的字符串,调用后未释放会导致内存泄漏;若分配内存大小不足,也会触发越界错误。
4. 函数调用逻辑错误
比如先转小写再过滤非字母,或过滤后未正确传递处理后的字符串给回文判断函数,导致判断的还是原字符串。
修复后的完整代码
#include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> // 移除非字母字符,返回动态分配的新字符串 char* checker(const char *str) { int len = strlen(str); char *filtered = (char*)malloc(len + 1); if (!filtered) { perror("malloc failed"); exit(EXIT_FAILURE); } int idx = 0; for (int i = 0; i < len; i++) { // 转unsigned char避免isalpha处理负数的未定义行为 if (isalpha((unsigned char)str[i])) { filtered[idx++] = str[i]; } } filtered[idx] = '\0'; // 必须添加字符串结束符 return filtered; } // 将传入的可写字符串统一转为小写 void lowerCase(char *str) { for (int i = 0; str[i] != '\0'; i++) { str[i] = tolower((unsigned char)str[i]); } } // 判断字符串是否为回文 int isPalindrome(const char *str) { int left = 0; int right = strlen(str) - 1; while (left < right) { if (str[left] != str[right]) { return 0; // 不是回文 } left++; right--; } return 1; // 是回文 } int main() { char input[100]; // 使用栈上可写数组存储输入 printf("请输入字符串:"); fgets(input, sizeof(input), stdin); // 移除fgets读取的换行符 input[strcspn(input, "\n")] = '\0'; // 按顺序执行处理逻辑 char *filtered = checker(input); lowerCase(filtered); int result = isPalindrome(filtered); printf(result ? "该字符串是回文\n" : "该字符串不是回文\n"); free(filtered); // 释放动态分配的内存,避免泄漏 return 0; }
关键修复说明
checker函数:用动态分配内存存储过滤结果,避免修改只读内存;遍历字符时转unsigned char,避免isalpha处理负数的未定义行为;手动添加'\0'保证字符串合法。lowerCase函数:同样转unsigned char确保tolower处理正确,仅修改可写字符串。isPalindrome函数:采用左右指针双向比对,逻辑高效简洁。- 主函数:用
fgets读取输入避免缓冲区问题;调用strcspn移除换行符;记得释放checker分配的内存。
内容的提问来源于stack exchange,提问作者dundern
相关产品推荐
相关产品推荐

