You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:05:35