我有一个检测回文的c程序。它还可以检测带有空格的回文。如果字符串为空,则返回-1;如果是回文,则返回1,否则返回0。这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int pal(char *str){
if(str[0] == '\0'){
return -1;
}else{
size_t i = 0;
size_t j = strlen(str) - 1;
while(*(str + i) != '\0'){
if(*(str + i) == ' '){
i++;
continue;
}else if(*(str + j) == ' '){
j--;
continue;
}else{
if(*(str + i) != *(str + j)){
return 0;
}
}
i++;
j--;
}
return 1;
}
}
int main(){
char *str = "a man a plan a canal panama";
printf("%d", pal(str));
printf("\n");
return 0;
}
当我在本地机器上编译并运行该程序时,它工作正常。但是当我将其上传到我的CS课程的INGInious问题时(INGInious是一个人们可以上传他们关于特定主题的答案并且系统会对其进行评论的平台),它会导致分段错误。是否有任何可能导致我不知道的SegFault的情况?
就像我在评论中说的那样,你不能控制j
的值,因为你的代码可能会表现出未定义的行为 - 当j变为0时,你继续减少它,它会绕回并成为size_t
类型的最大值(现代平台上令人印象深刻的数字)。
使用您提供的字符串不会发生这种情况,但是,我想您的测试平台会在另一个字符串上测试它(这是我对崩溃的唯一解释)。
例如,您的代码将在以下字符串中暴露于未定义的行为:"a bcd"
你的代码太复杂了。
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
bool is_palindrome(char const *str)
{
size_t length = strlen(str);
for (char const *front = str, *back = str + length - 1; front != back; ++front, --back) {
while (isspace((char unsigned) *front) && front != str + length - 1)
++front;
while (isspace((char unsigned) *back) && back != str)
--back;
if (front == back)
break;
if (*front != *back)
return false;
}
return true;
}
int main(void)
{
char const *foo = "a man a plan a canal panama";
printf("%d\n", is_palindrome(foo));
char const *bar = "hello";
printf("%d\n", is_palindrome(bar));
}
1
0
在下面的循环中:
while(*(str + i) != '\0'){
if(*(str + i) == ' '){
i++;
continue;
}else if(*(str + j) == ' '){
j--;
continue;
}else{
if(*(str + i) != *(str + j)){
return 0;
}
}
i++;
j--;
}
当*(str + i) == '\0'
,它应该是i == strlen(str)
和j == -1
(如果字符串中没有空格。否则我不太确定)这可能是问题。但同样,我真的看不到你不会访问str
超出范围。我建议这样做,以使您的循环更容易看到终止条件:
while(i < j){
// ...
}