3

コマンドライン引数として文字列を受け入れています。入力した文字列が回文かどうかを確認し、結果を出力したい。私は次のコードを書きました。ただし、すべての入力に対して「パリンドロームではない」という結果が表示されます。

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

int main(int argc, char argv[20]) {
    int i;
    int l = strlen(argv);    
    char str[20];
    bzero(str, 20);

    for(i=0; i<l; i++)
    {
        str[i] = argv[i+2];
    } 
    int flag;
    int len = strlen(str);
    for(i=0; i< len/2; i++)
    {
        if(str[i] == str[len - (i+2)])
        {
            flag = 0;
        }
        else
        {
            flag = 1;
            break;
        }
    }

    if(flag == 0)
        printf("Palindrome\n");
    else
        printf("Not a palindrome\n");
}
4

6 に答える 6

5

for-loopに 2 つのオフセット イテレータを含めることで、K&R スタイルでそれを行うことができます。

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

int main(int argc, char *argv[]) {
    assert(argc != 1);

    char *text = argv[1];

    int len = strlen(text);
    int is_palindrome = 1;
    int i, j;

    for(i = 0, j = len - 1; i < len / 2; i++, j--) {
        if(text[i] != text[j]) {
            is_palindrome = 0;
            break;
        }
    }

    printf("%s a palindrome.\n", is_palindrome ? "is" : "isn't");

    return(0);
}

オリジナルからの変更点:

  • Tenfour が提案したように、shift(len >> 1) を division(len / 2) に変更しました。
于 2010-08-12T21:44:05.257 に答える
2

コメントに基づいて更新:

int is_palindrome(const char *s)
{
   const char *t = s + strlen(s);
   while (s<t && *s==*--t) s++;
   return s>=t;
}

また、OP はポインターがそれほど重くないバージョンを必要としているため、次のようになります。

int is_palindrome(const char *s)
{
   size_t i=0, j = strlen(s);
   while (i<j && s[i]==s[--j]) i++;
   return i>=j;
}

参考までに、元のバグのあるバージョンは次のとおりです。

int is_palindrome(const char *s)
{
   const char *t = s + strlen(s) - 1;
   while (s<t && *s++==*t--);
   return s>=t;
}
于 2010-08-13T07:15:01.550 に答える
1

一つには、あなたの署名mainがオフになっています。int main(int argc, char** argv)またはである必要がありますint main(int argc, char * argv[])。文字列へのポインタを文字列であるかのように扱っています。

それを変更したら、必要な文字列が含まれているはずですargv[1]argv[0]プログラム名の表現であるため)。

于 2010-08-12T19:11:37.553 に答える
1

これには、インデックスではなくポインターを使用する良いケースがあります。

int is_palindrome(const char *s) {
    const char *end = s + strlen(s);
    while (end > s) {
        --end;
        if (*end != *s) return 0;
        ++s;
    }
    return 1;
}

短くて紛らわしいコードが好きなら、次のように書き直すことができます。

int is_palindrome(const char *s) {
    const char *end = s + strlen(s);
    while (end > s) if (*(--end) != *(s++)) return 0;
    return 1;
}

argvは文字列ではなく、文字列の配列で、プログラム名用に 1 つ、次に各引数用に 1 つです (通常、コマンド ラインではスペースで区切られます)。したがって、最初の引数が回文であるかどうかをテストするには、argv[1] に関心があります。

int main(int argc, char **argv) {
    if (argc != 2) {
        printf("usage: %s <string>\n", argv[0]); // or something
        return 1;
    }
    if (is_palindrome(argv[1])) {
        printf("Palindrome\n");
    } else {
        printf("Not a Palindrome\n");
    }
}
于 2010-08-13T01:30:55.153 に答える
0

ポインターはありません (元の文字列のコピーを作成するために使用されるものを除く)。

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

int main( int argc, char *argv[] )
{
    char    *s2;

    if ( argc != 2 )
        return ( 1 );   //  not properly invoked

    if ( (s2 = strdup( argv[1] )) == NULL )
        return ( 2 );   //  failed (not likely)

    printf( "\"%s\" %s a palindrome.\n", argv[1], strcmp( argv[1], strrev( s2 ) ) ? "is not" : "is" );

    free( s2 );

    return ( 0 );
}
于 2010-08-14T07:47:23.487 に答える
0

最初のループは意味がありません。文字列を別のものにコピーしても意味がありません。

それをしてインデックスを調整するだけです:

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

int main(int argc, char **argv) {
int i;
char * str = argv[1];
int flag;

int len = strlen(str);

for(i=0; i< (len+1)/2; i++)
{

    printf("DEBUG: Comparing %c %c\n",str[i], str[len - (i+1)]);


    if(str[i] == str[len - (i+1)])
    {
        flag = 0;
    }
    else
    {
        flag = 1;
        break;
    }
}

    if(flag == 0)
    printf("Palindrome\n");
else
    printf("Not a palindrome\n");
}
于 2010-08-12T19:34:30.793 に答える