我有一个检测回文的c程序。它还可以检测到带有空格的回文。如果字符串为null,则返回-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的情况?
答案 0 :(得分:2)
就像我在评论中说的那样,您无法控制j
的值,因此您的代码可能表现出未定义的行为-当j变为0时,但您保持减小它,它会回绕并变成size_t
类型的最大值(在现代平台上相当可观的数字)。
您提供的字符串不会发生这种情况,但是,我想您的测试平台会在另一个字符串上对其进行测试(这是我对崩溃的唯一解释)。
例如,您的代码将在以下字符串上暴露于未定义的行为:"a bcd"
答案 1 :(得分:0)
您的代码太复杂了。
#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
答案 2 :(得分:-2)
在下面的循环中:
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){
// ...
}