2017-10-14 54 views
0

我正在编写一个程序来检查回文。我最近拿起C并想知道为什么我不能使用它吗?是否有一些与我利用直接复制的argv成字符数组复制argv并检查回文

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

int main(int argc,char *argv[]){ 
    int i; 
    int a; 
    int size; 


    for(a = 1; a < argc; a++){ 
     char *reverseThis = argv[a]; 
     char *normal = argv[a]; 
     size = strlen(reverseThis); 
     for(i = 0; i < size; i++){ 
      reverseThis[i] = normal[size - i - 1]; 
     } 
     for(i = 0; i < size; i++){ 
     reverseThis[i] = tolower(reverseThis[i]); 
     normal[i] = tolower(normal[i]); 
     } 
     if(strcmp(reverseThis,normal)==0){ 
      printf("\"%s\": on palindromi\n",argv[i]); 
     } 
     else 
      printf("\"%s\": ei ole palindromi\n",argv[i]); 
    } 
    return 0; 
} 
+2

既不'字符* reverseThis = argv的[A];''也不字符* =正常的argv [A];'副本,则在相同的串/'char'阵列指向两个指针 - 复制完成通过['strcpy'](http://en.cppreference.com/w/c/string/byte/strcpy)函数 – UnholySheep

回答

0

您使用的是不正确的做法。

对于初学者来说这个循环

for(i = 0; i < size; i++){ 
    reverseThis[i] = normal[size - i - 1]; 
} 

的字符串复制的右半部分以相反的顺序在完全覆盖其左边部分字符串的左半部。

例如,如果你有这样"123456"一个字符串,然后在循环之后它看起来就像"654456"

这种比较也没有任何意义

if(strcmp(reverseThis,normal)==0){ 

因为两个指针指向相同的字符串。所以这个条件总是正确的。

要考虑到这些声明

char *reverseThis = argv[a]; 
char *normal = argv[a]; 

不要复制原始字符串通过argv[a]指向。声明的指针只是指向同一个字符串的第一个字符。

这里是一个错字

printf("\"%s\": on palindromi\n",argv[i]); 
            ^^^ 

任务可以做简单而不改变字符串。

例如

size_t n = strlen(argv[a]); 
size_t i = 0; 

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

if (i == n/2) 
{ 
    printf("\"%s\": on palindromi\n", argv[a]); 
} 
else 
{ 
    printf("\"%s\": ei ole palindromi\n",argv[a]); 
} 

如果确实需要复制串然后或者声明可变长度数组(当编译器支持它们)或动态地分配阵列。例如(声明可变长度数组):

size = strlen(argv[a]); 
char reverseThis[size + 1]; 
char normal[size + 1]; 

strcpy(reverseThis, argv[a]); 
strcpy(normal, argv[a]); 
-3

第一“如果”在索引从argv的采取的“i”,我==来,在过去已经改变的“for”,在你的情况下,最后变化i == 4,程序崩溃导致它们在该成员中不是字符串,因此修复了在“if”之前应将“i”更改为0。

0

在您的代码中,您没有复制字符串,您将normalreverseThis都分配给了相同的字符串argv[a]。反之,您需要在分配内存后复制argv[a]。 只需修改for循环代码:

for(a = 1; a < argc; a++){ 

    char *normal = argv[a]; 
    size = strlen(normal); 
    char *reverseThis = (char*)malloc((size+1)*sizeof(char)); 
    int j=0; 
    for(i = size-1; i >= 0; i++){ 
     reverseThis[j++] = normal[i]; 
    } 
    reverseThis[j]='\0'; 
    . 
    . 
0

你并不需要扭转字符串和比较,找出输入字符串是否是回文与否。

您可以简单地比较从字符串两端开始的字符串字符,并从字符串开头向前移动一个字符,并从字符串末尾向后移动一个字符。如果所有字符匹配,直到达到字符串中间,则字符串是回文,否则不是回文。

#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 
int main(int argc,char *argv[]){ 
    int i, a, size; 

    for(a = 1; a < argc; a++){ 
     char *ptr= argv[a]; 
     int notpalindrom = 0; 

     size = strlen(ptr) - 1; 
     for(i = 0; i < size;){ 
      if (tolower(ptr[i++]) != tolower(ptr[size--])){ 
       notpalindrom = 1; 
       break; 
      } 
     } 
     if (notpalindrom) 
      printf ("%s is not palindrom\n", ptr); 
     else 
      printf ("%s is palindrom\n", ptr); 
    } 
    return 0; 
}