无法进行回文检查

时间:2015-07-01 19:40:17

标签: c function

我正在编写一个代码来检查输入的字符串是否是回文,在C中。到目前为止,我已经编写了函数来反转输入字符串并将原始字符串与反向字符串进行比较。无论输入是什么,输出总是“不是回文”。代码中某处有错误吗?或者我必须尝试不同的方法?代码如下所示。

#include <stdio.h>
#include <string.h>

void reverse(char *string);
int testStrings(char *a, char *b);

int main()
{
    char string[100];
    char string2[100];

    printf("Please Enter a string:\n");
    fgets(string, 100, stdin);
    strcpy(string2, string);
    reverse(string);

    printf("Here's what you typed:%s\n",string2);
    printf("Here's the Reversed:%s\n",string);
    testStrings(string, string2);

    return 0;
}

void reverse(char *s)
{
    int c, i , j;
    for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
    return;
}

int testStrings(char *a, char *b)
{
    int i;
    int length;
    int c;

    length = strlen(b) - 1;

    for (i = 0; 1 <= length; i++) {
        if (b[i] != a[i]) {
            c = 1;
            break;
        }
    }

    if (c = 1) {
        printf("The input is not a palindrome.\n");
    } else {
        printf("The inpiy is a palindrome.\n");
    }

    return 0;
}

7 个答案:

答案 0 :(得分:0)

函数fgets还包括字符串中与按Enter键对应的新行字符。如果字符串中存在,则应将其删除。例如

size_t n = strlen( string );

if ( n && string[n-1] == '\n' ) string[--n] = '\0';

考虑到最好从函数中排除print语句 testStrings并将它们放在主要内容中。该函数应返回1或0,具体取决于字符串是否相等。并且无需在函数内调用strlen

该函数可以编写得更简单,并且看起来如下

int testStrings( const char *s1, const char *s2 )
{
    while ( *s1 && *s1 == *s2 ) ++s1, ++s2;

    return *s1 == *s2;
}

对于函数反转,最好以这样的方式编写它,以便在目标字符串中以相反的顺序复制源字符串。例如

char * reverse_copy( char *s1, const char *s2 )
{
    char *p = s1;
    const char *q = s2 + strlen( s2 );

    while ( q != s2 ) *p++ = *--q;

    *p = '\0';

    return s1;
}

该函数调用woul看起来像

printf( "Here's what you typed:%s\n", string );
printf( "Here's the Reversed:%s\n", reverse_copy( string2, string ) );

int isPalindrome = testStrings( string, string2 );

// print stetements depending on whether the result is equal to 1 or 0

现在,如果要将所有这些组合在一起,您可以获得以下程序

#include <stdio.h>
#include <string.h>

int testStrings( const char *s1, const char *s2 )
{
    while ( *s1 && *s1 == *s2 ) ++s1, ++s2;

    return *s1 == *s2;
}

char * reverse_copy( char *s1, const char *s2 )
{
    char *p = s1;
    const char *q = s2 + strlen( s2 );

    while ( q != s2 ) *p++ = *--q;

    *p = '\0';

    return s1;
}

#define N   100

int main( void ) 
{
    char string[N];
    char string2[N];

    printf( "Please Enter a string: " );
    fgets( string, N, stdin );

    size_t n = strlen( string );

    if ( n && string[n-1] == '\n' ) string[--n] = '\0';

    printf( "\nHere's what you typed: %s\n", string );
    printf( "Here's the Reversed: %s\n", reverse_copy( string2, string ) );

    if ( testStrings( string, string2 ) )
    {
        printf( "\nThe input is a palindrome.\n" );
    }
    else
    {
        printf( "\nThe input is not a palindrome.\n" );
    }

    return 0;
}

如果要输入例如

123454321

然后输出

Please Enter a string: 123454321

Here's what you typed: 123454321
Here's the Reversed: 123454321

The input is a palindrome.

考虑到您可以在不使用第二个字符数组的情况下确定字符串是否为回文结构。在这种情况下,该函数可以采用以下方式

int isPalindrome( const char *s )
{
    size_t n = strlen( s );
    size_t i = 0;

    while ( i < n / 2 && s[i] == s[n-1-i] ) ++i;

    return i == n / 2;
}

答案 1 :(得分:0)

这不适用于fgets,因为它会使字符串跟踪\n; gets不这样做。

来自documentation

  

换行符使fgets停止读取,但它被函数视为有效字符,并包含在复制到str的字符串中。

要解决此问题,请调整长度以考虑尾随\n标记:转到字符串的末尾,然后再向后移动,直到看到非\n字符。

我尝试编辑你的代码并且它有效。勘误表if (c=1)1<=length我已修复。

#include <stdio.h>
#include <string.h>

void reverse(char *string);
int testStrings(char *a, char *b);

int main()
{
    char string[100];
    char string2[100];

    printf("Please Enter a string:\n");
    fgets(string, 100, stdin);


    size_t n = strlen( string );

    if ( n && string[n-1] == '\n' ) string[--n] = '\0';


    strcpy(string2, string);
    reverse(string);

    printf("Here's what you typed:%s\n",string2);
    printf("Here's the Reversed:%s\n",string);
    testStrings(string, string2);

    return 0;
}

void reverse(char *s)
{
    int c, i , j;
    for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
    return;
}

int testStrings(char *a, char *b)
{
    int i;
    int length;
    int c;

    length = strlen(b) - 1;

    for (i = 0; i < length / 2; i++) {
        if (b[i] != a[i]) {
            c = 1;
            break;
        }
    }

    if (c == 1) {
        printf("The input is not a palindrome.\n");
    } else {
        printf("The inpiy is a palindrome.\n");
    }

    return 0;
}

答案 2 :(得分:0)

如果仔细查看程序输出,您会发现还有一个newline。我输入了abcdef并报告了

Here's what you typed:abcdef
          <--- extra blank line here>
Here's the Reversed:
fedcba
The input is not a palindrome.

您的代码不会生成额外的newline,而代码会打印一个换行符

printf("Here's what you typed:%s\n",string2);
printf("Here's the Reversed:%s\n",string);

这是因为fgets将终止newline作为字符串的一部分。

我最喜欢的方法是删除newline所包含的尾随fgets

string [ strcspn(string, "\r\n") ] = 0;

因为它会处理文本文件行尾的不同操作系统约定而不会抱怨。

答案 3 :(得分:0)

您可以做的第一件事就是将fgets(string, 100, stdin)替换为gets(string),因为\n

包含了fgets()字符。

更多,在testStrings()你应该

  • int c=0初始化c。
  • for (i = 0; i <= length; i++) {将1更改为i
  • if (c == 1) {=更改为==

以下是包含上述更改的完整工作代码:

 #include <stdio.h>
 #include <string.h>

 void reverse(char *string);
 int testStrings(char *a, char *b);
 int main()
 {
   char string[100];
   char string2[100];

   printf("Please Enter a string:\n");
   gets(string);
   strcpy(string2, string);
   reverse(string);

   printf("Here's what you typed:%s\n",string2);
   printf("Here's the Reversed:%s\n",string);
   testStrings(string, string2);
   return;
 }

void reverse(char *s)
{
    int c, i , j;
    for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
   return;
}

int testStrings(char *a, char *b)
{
   int i;
   int length;
   int c=0;

   length=strlen(b)-1;
   for(i=0;i <=length; i++)
   {
         if(b[i]!=a[i])
        {
        c = 1;
        break;
        }
   }
   if(c==1)
   {
      printf("The input is not a palindrome.\n");
   }
   else
   {
      printf("The inpiy is a palindrome.\n");
   }
   return 0;
}

另外要提到的是,您可以使用更好的算法来检查回文。

答案 4 :(得分:0)

这是一个非常多的代码。你必须扭转字符串吗?这是一个要求吗?一个可选的解决方案。

int main(int argc, char* argv[]) {
    if (argc < 2) {
        printf("Need an argument\n");
        return -1;
    }

    int len = strlen(argv[1]) - 1;
    int i = 0;
    int palindrome = 1;
    for ( ; i < len; ++i, --len) {
        if (argv[1][i] != argv[1][len]) {
            palindrome = 0;
            break;
        }
    }

    if (palindrome) {
        printf("I am a Palindrome\n");
    }
    else {
        printf("I am NOT a Palindrome\n");
    }
    return 0;
}

答案 5 :(得分:0)

不是您问题的直接答案,但这是一个更清洁的解决方案:

public float BoundingBox(RoadNode[] nodes)

答案 6 :(得分:0)

#include <stdio.h>
#include <string.h>

int main()
{
    char string[100];

    printf("Please Enter a string:\n");
    fgets(string, 100, stdin);

    size_t len = strlen(string) - 1;
    if (string[len] == '\n') len --;

    for (size_t left = 0; left < len && string[left] == string[len]; ++left, --len) { }

    printf("%s is %s palidrome\n", string, (left < len ? " not a ", ""));
    return 0;
}

最小的我可以获得合理可读的代码。