测试Palindrome的C代码为何无法处理含空格标点的回文字符串?
以下是用于测试字符串是否为Palindrome(回文字符串)的代码。字符串可包含任意数量的空格、标点符号(., ?, !, ,),且区分大小写。该代码可处理如下字符串:
"madam", "racecar", "radar"
但无法处理以下字符串:
"a man a plan a canal panama", "a man a pla n a cana L Panama", "Cigar? Toss it in a can, It is sotragic"
对应的C代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char string[100]; printf("Enter a string: "); scanf("%[^\n]", string); int isPalindrome = 1; // assign 0 to this if the string is a NOT palindrome // code to test if string is a palindrome char str1[100], str2[100]; int len = strlen(string) - 1; int i; for (i = 0; i <= len; i++) { if (string[i] == '?' || string[i] == '.' || string[i] == '!' || string[i] == ',' || string[i] == ' ') { i++; } strcpy(str1, string); } int length = strlen(str1) - 1; int j, k; for (j = length; j >= 0; j--) { str2[j] = str1[len - j]; } k = strcmp(str2, str1); // at the end you need to test if (k == 0) { printf("Yes, it is Palindrome!\n"); } else { printf("No, not a Palindrome\n"); } return 0; }
请问为何这段测试Palindrome的C代码无法处理含空格、标点及大小写混合的回文字符串?
这段代码无法处理目标字符串的核心原因在于以下几个关键错误:
空格处理完全错误
代码中判断空格的条件是string[i] == ' ',这是非法的字符常量——C语言中字符常量只能是单个字符,正确的单个空格应该是' '。另外,遇到标点/空格时执行i++,再加上循环本身的i++,会导致跳过两个字符,可能遗漏有效字符的处理。未真正过滤无关字符
循环里每次都执行strcpy(str1, string),这意味着str1始终和原始输入字符串完全一致,根本没有把空格、标点等无关字符过滤掉。正确的逻辑应该是遍历原始字符串,只把字母字符复制到str1中,而不是直接拷贝原串。未统一大小写
代码完全没有处理大小写差异,比如输入中的L和l会被strcmp判定为不同字符,而回文判断需要忽略大小写(比如Panama和panama应该视为一致)。需要将所有字符转换为大写或小写后再进行比较。字符串反转逻辑错误
反转字符串时使用了原字符串的长度len而非str1的长度,导致索引计算错误;同时str2没有添加字符串终止符'\0',strcmp函数要求字符串必须以'\0'结尾,否则会读取内存中的垃圾数据,导致比较结果错误。输入读取存在隐患
scanf("%[^\n]", string)没有限制读取长度,当输入字符串超过99个字符时会导致缓冲区溢出;如果之前的输入残留了换行符,还会直接读取空字符串,应该改为scanf("%99[^\n]", string),并在读取前清理输入缓冲区。
内容的提问来源于stack exchange,提问作者Kendal

