2017-10-14 3 views
0

私はパリンドロームをチェックするプログラムを書いています。私は最近Cを取り上げて、それがうまくいかない理由があるのだろうかと疑問に思っていました。 argvをchar配列に直接コピーするのと何か関係がありますか?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

どちらもない 'のchar * reverseThis = ARGV [A];'や 'のchar *ノーマル= 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"ような文字列を持っている場合たとえば

は、ループの後には、両方のポインタが同じ文字列を指しているので、センス

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

がありません"654456"

のように、この比較になります。したがって、条件は常に真となります。

これらの宣言

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」は、私はあなたの場合には、「用」最後に変更された最後の変更に== i == 4、プログラムがクラッシュして、そのメンバーの文字列ではなく、 "if"の前に "i"を0に変更しなければならないという問題を修正しました。あなたのコードで

0

あなたは同じ文字列を使用すると、メモリを割り当てた後argv[a]をコピーする必要がargv[a] .IN reverseThisをnormalreverseThisの両方を割り当て、文字列をコピーしていません。 ただ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

あなたは、文字列を逆にして、入力文字列が回文であるかどうかを調べるために比較する必要はありません。

文字列の両端から始まる文字列を単純に比較し、文字列の先頭から1文字前方に、文字列の最後から1文字後に移動することができます。文字列の中央に達するまですべての文字が一致する場合、文字列は回文文字列であり、そうでない場合は回文文字列ではありません。

#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; 
} 
関連する問題