这是在学校的家庭作业。我不是要求正确的答案只是推动正确的方向。关于为什么会出错的解释将是很好的以及对正确方法的解释。这个C程序应该做的是读取没有空格和标点符号的用户输入并将其分配给字符数组字符串。然后应该将该数组传递给函数回文。 Palindrome应该是字符串的长度,如果等于1或0,则返回TRUE或1,否则移动并检查字符串的第一个和最后一个字符。如果它们匹配则检索第二个和第二个到最后一个字符,以及它们之间的所有字符,并将其传递到函数回文中。
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#define TRUE 1
#define FALSE 0
typedef int Bool;
Bool palindrome(char str[]);
main()
{
char string[1000], ch;
int i = 0;
printf("Enter a message: ");
while((ch = getchar()) != '\n'){
if(isspace(ch)==FALSE || ispunct(ch)==FALSE);
string[i] = tolower(ch);
i++;
}
string[i] = '\0';
printf("\n");
if(palindrome(string))
printf("Palindrome\n");
else
printf("Not a palindrome\n);
return 0;
}
Bool palindrome(char str[])
{
int length = strlen(str);
if((length == 1) || (length == 0))
return TRUE;
else
{
if((str[0] == str[length - 1])
{
char str_new[length-1];
int i, j;
for(i = 1, j = 0; str[i]!=str[length-1]; i++, j++)
str_new[j] = str[i];
str_new[i] = '\0';
palindrome(str_new);
}
else
return FALSE;
}
}
无论输入的是什么,总是打印出来的字符串不是回文。例如,当我输入
时他是一个魔鬼,呃?
打印出来
不是回文
当我编辑程序以使用之前的输入检查数组字符串中的内容时,它是
他是一个魔鬼,呃?
您可以随意评论我看到代码使用改进的代码的任何其他方面。他们真的不提供任何东西,除了是的权利,或者不是我们的代码。
编辑:
我确实检查了char数组中的值是什么。我在最后一个blockquote之前说这个。
答案 0 :(得分:1)
看看这里......
while((ch = getchar()) != '\n'){
if(isspace(ch)==FALSE || ispunct(ch)==FALSE);
string[i] = tolower(ch);
i++;
}
注意';'在if语句的末尾。那'''导致字符串[i] = tolower(ch)始终执行。另外,你的逻辑是不正确的,如果字符不是空格并且它不是标点符号,你想要执行代码。
另外,请注意缩进。 i ++也应该在if语句中,但它缺乏围绕它的括号。因此,即使您确实删除了';',i ++仍将始终执行。所以......
while((ch = getchar()) != '\n'){
if(isspace(ch)==FALSE && ispunct(ch)==FALSE)
{
string[i] = tolower(ch);
i++;
}
}
或者......甚至更好......
while((ch = getchar()) != '\n'){
if(isspace(ch)==FALSE && ispunct(ch)==FALSE)
string[i++] = tolower(ch);
}
样式注释...为了维护和可读性,从函数中获得单个退出点通常是个好主意。其他人可能会有不同的争论,但这是过去30年来我在国防部工作中所经历的艰难而快速的规则。看看这个是否具有可读性,看看它是否对你更有意义。
Bool palindrome(char str[])
{
Bool result = TRUE;
int length = strlen(str);
if( length > 1 && str[0] == str[length-1] )
{
char str_new[length-1];
int i, j;
for(i = 1, j = 0; str[i]!=str[length-1]; i++, j++)
str_new[j] = str[i];
str_new[i] = '\0';
result = palindrome(str_new);
}
return result;
}
最后......从效率的角度来看,你可以轻松地将其编入索引,而不是复制字符串......
Bool palindrome(char str[])
{
Bool result = TRUE;
int length = strlen(str);
if( length > 1 && str[0] == str[length-1] )
{
str[length-1] = '\0';
result = palindrome(&str[1]);
}
return result;
}
答案 1 :(得分:1)
if(isspace(ch)==FALSE || ispunct(ch)==FALSE);
这是你的错。首先,最后不应该有分号(;
)。
其次,你不应该使用OR,你应该使用AND,因为你想确保你过滤掉除字母表之外的所有内容:
if(isspace(ch)==FALSE && ispunct(ch)==FALSE)
此外:
for(i = 1, j = 0; str[i]!=str[length-1]; i++, j++)
这里,布尔表达式是错误的。您应该评估j
:
for(i = 1, j = 0; j < length - 1; i++, j++)
最后,当您将字符附加到新字符串时,您对i++
语句的定位是不正确的。将它放回去,以便编译器知道它需要成为while循环体的一部分并且在if块之外。
答案 2 :(得分:0)
一些明显的观点:
if
语句在行尾有一个错误的分号。要做的关键更改是您的if
声明应如此:
if (!isspace(ch) && !ispunct(ch))
完整的工作程序如下所示:
#include<stdio.h>
#include<string.h>
#define TRUE 1
#define FALSE 0
typedef int Bool;
Bool palindrome(char str[]);
int main(void)
{
char string[1000], ch;
int i = 0;
printf("Enter a message: ");
while((ch = getchar()) != '\n'){
if (!isspace(ch) && !ispunct(ch))
{
string[i] = tolower(ch);
i++;
}
}
string[i] = '\0';
printf("string = %s\n", string);
if(palindrome(string))
printf("Palindrome\n");
else
printf("Not a palindrome\n");
return 0;
}
Bool palindrome(char str[])
{
int left = 0;
int right = strlen(str)-1;
while (left<right)
{
if(str[left] != str[right])
return FALSE;
left++;
right--;
}
return TRUE;
}
这是输出:
Enter a message: He lived as a devil, eh? string = helivedasadevileh Palindrome