0

这是学校的家庭作业。我不是要求正确的答案,只是朝着正确的方向前进。关于为什么会出错的解释以及对正确方法的解释会很好。这个 C 程序应该做的是在没有空格和标点符号的情况下读取用户输入并将其分配给字符数组字符串。然后应该将该数组传递给函数回文。回文应该是字符串的长度,如果等于 1 或 0,则返回 TRUE 或 1,否则继续检查字符串的第一个和最后一个字符。如果它们匹配,则检索倒数第二个和第二个字符,以及它们之间的所有字符,并将其传递给函数 palindrome。

#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 数组字符串中的值是什么。我在最后一个引用之前说这个。

4

3 回答 3

1

看看这里...

while((ch = getchar()) != '\n'){
  if(isspace(ch)==FALSE || ispunct(ch)==FALSE);
    string[i] = tolower(ch);
    i++;
}

注意';' 在 if 语句的末尾。那 ';' 导致 string[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;
}
于 2013-03-23T16:51:56.333 回答
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 块之外。

于 2013-03-23T16:53:20.317 回答
0

一些明显的点:

  • 问题中的代码无法编译。
  • 您的主要声明不标准。
  • if语句在行尾有一个错误的分号。
  • 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;
}

这是输出:

输入一条消息:他像魔鬼一样生活,嗯?
字符串 = helivedasadevileh
回文
于 2013-03-23T16:58:40.400 回答