2017-06-12 37 views
1

我在想为什么结果不正确。 如果我输入字符串来测试字符串是否是回文, 每当我尝试时结果都是一样的。回文 - 只有C语言

例如,如果我键入'爸爸'来测试,这表明我不是回文。然而,如果我键入'神',它仍然表明我不是回文。

我不知道如何以正确的方式解决这个问题... 请让我知道我该如何做到这一点。

谢谢。

(以下代码)

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

void isPalindrome(char *str, int n); 

int main() { 
    char str[100]; 
    int n = strlen(str); 
    char choice; 
    printf("Will you run this program? : "); 
    scanf("%c", &choice); 
    getchar(); 

    while (choice == 'Y' || choice == 'y') { 
     isPalindrome(str, n); 
     printf("Retry? : "); 
     scanf("%c", &choice); 
     getchar(); 
    } 
} 

void isPalindrome(char *str, int n) { 
    int flag = 1; 
    printf("Type strings : "); 
    gets_s(str, 100); 

    for (int i = 0; i < n/2; i++) { 
     if ('A' <= str[i] && str[i] <= 'Z') { 
      str[i] = str[i] - 'A' + 'a'; 
     } 

     if (strlen(str)/2 == 0) { 
      if (str[i] != str[n - i - 1]) { 
       flag = 0; 
       break; 
      } 
     } else 
     if (strlen(str)/2 != 0) { 
      if (str[i] != str[n - i]) { 
       flag = 0; 
       break; 
      } 
     } 
    } 
    if (flag == 1) { 
     printf("%s is a palindrome \n", str); 
    } else { 
     printf("%s is not a palindrome \n", str); 
    } 
} 
+7

现在是学习如何使用调试器的好时机。 – OldProgrammer

+1

'(strlen(str)/ 2 == 0)'没有任何意义。也许你的意思是'(strlen(str)%% 2 == 0)'? – Shark

+4

“*你会运行这个程序吗?*” - 但是......但是......我不是已经这么做了吗? –

回答

1

下面是一个示例实现,你可以使用包括C语言编程的良好做法,也是使用内置的功能tolower()不区分大小写:

Try it online!

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

bool isPalindrome(char*, size_t); 
void printIsPalindrome(char*); 

int main() { 
    printIsPalindrome("abba"); 
    printIsPalindrome("abbccbba"); 
    printIsPalindrome("aBBcCbbA"); 
    printIsPalindrome("geeks"); 
    printIsPalindrome(""); 

    return 0; 
} 

bool isPalindrome(char* buf, size_t len) { 
    size_t i = 0; 
    size_t j = len; 
    char a; 
    char b; 

    while (j > i) { 
     a = tolower(buf[i++]); 
     b = tolower(buf[--j]); 

     if (a != b) { 
      return false; 
     } 
    } 

    return true; 
} 

void printIsPalindrome(char* str) { 
    if (isPalindrome(str, strlen(str))) { 
     printf("%s is a palindrome\r\n", str); 
    } else { 
     printf("%s is not a palindrome\r\n", str); 
    } 
} 

本质上,你想分开你的驱动逻辑从实施检查是否字符串是回文或不是。这就是为什么该功能分为isPalindrome()printIsPalindrome()

函数检查条件是否是真还是假不应该输出到控制台的副作用,这是一般的一个很好的做法,而不只是在C.

的通用功能,预计(即isPalindrome())也不应该假定传递的缓冲区(char* buf)是一个C字符串,所以检查strlen()应该只在驱动程序代码printIsPalindrome()中执行,而不是可移植逻辑。原因是为了避免缓冲区溢出攻击带来的安全漏洞,假设其他人打算在他们的程序中使用isPalindrome()作为依赖关系。它允许它们指定它们显式传递的缓冲区的大小,因此它可以验证缓冲区是否被访问超出分配的内存块。

最后,任何在缓冲区(ij)的索引检查应size_t以可移植代码,size_t是保证足够大,以解决所有的内存空间,同时int不认为保证。

+0

'isPalindrome'对于空字符串有未定义的行为。 – chqrlie

+0

@chqrlie良好的捕获。我已经更新了我的答案。 –

3

对于按照C标准的主要功能不带参数起动器应声明如下

int main(void) 

功能isPalindrome应该做的只有一件事 - 检查提供的字符串是否是回文。所有的输入都应该在main中完成。

此外,由于函数不会更改字符串本身,因此应使用限定符const声明相应的参数。

函数应具有返回类型int_Bool

这第二份声明中主要

char str[100]; 
int n = strlen(str); 

因为数组str既不包含字符串没有意义。此外,变量n的类型应为size_T,因为它是函数strlen的返回类型。

相反,这些操作

if ('A' <= str[i] && str[i] <= 'Z') 
    { 
     str[i] = str[i] - 'A' + 'a'; 
    } 

它是更好的使用标准功能tolower,你必须到字符串的两个符号同时转换的。

该程序可以看下面的方式。

#define __STDC_WANT_LIB_EXT1__ 1 

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

#define N 100 

int isPalindrome(const char s[], size_t n) 
{ 
    size_t i = 0; 

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

    return i == n/2; 
} 

int main(void) 
{ 
    char choice; 

    printf("Will you run this program? : "); 
    scanf(" %c", &choice); 
    getchar(); 

    while (choice == 'Y' || choice == 'y') 
    { 
     char s[N]; 

     printf("Type a string : "); 
     gets_s(s, N); 

     if (isPalindrome(s, strlen(s))) 
     { 
      printf("\"%s\" is a palindrome\n", s); 
     } 
     else 
     { 
      printf("\"%s\" is not a palindrome\n", s); 
     } 

     printf("Retry? : "); 
     scanf(" %c", &choice); 
     getchar(); 
    } 

    return 0; 
} 

程序输出可能看起来像

Will you run this program? : y 
Type a string : dad 
"dad" is a palindrome 
Retry? : y 
Type a string : god 
"god" is not a palindrome 
Retry? : n