web-dev-qa-db-ja.com

文字列を正しく比較する方法

ユーザーに単語や文字を入力させ、それを保存してから、ユーザーがもう一度入力するまで印刷してプログラムを終了させるプログラムを作成しようとしています。私のコードはこのようになります:

#include <stdio.h>

int main()
{
    char input[40];
    char check[40];
    int i=0;
    printf("Hello!\nPlease enter a Word or character:\n");
    gets(input);
    printf("I will now repeat this until you type it back to me.\n");

    while (check != input)
    {
        printf("%s\n", input);
        gets(check); 
    }

    printf("Good bye!");


    return 0;
}

問題は、ユーザーによる入力(チェック)が元の入力(入力)と一致する場合でも、入力文字列の印刷を取得し続けることです。 2つを間違って比較していますか?

162
nmagerko

!===を使って文字列を(便利に)比較することはできません。strcmpを使う必要があります。

while (strcmp(check,input) != 0)

これは、!===がこれらの文字列のベースアドレスのみを比較するためです。文字列自体の内容ではありません。

244
Mysticial

念のために言っておきますが、getsは安全ではないため、バッファオーバーフローが発生しないようにfgets(input, sizeof(input), stdin)に置き換えてください。

次に、文字列を比較するには、strcmpを使用する必要があります。戻り値0は、2つの文字列が一致することを示します。等号演算子(つまり!=)を使用すると、2つの文字列のアドレスが比較されます(それぞれの中の個々のcharsとは対照的です)。

また、この例では問題は発生しませんが、fgetsは改行文字'\n'をバッファにも格納します。 gets()は違います。 fgets()からのユーザ入力を"abc"のような文字列リテラルと比較した場合、それは決して一致しません(バッファが小さすぎて'\n'が収まらない場合を除く)。

編集:そして再び超高速神秘主義者によって殴ら。

30
AusCBloke

strcmp を使用してください。

これはstring.hライブラリにあり、非常に人気があります。文字列が等しい場合、strcmpは0を返します。 strcmpが返すもののより良い説明については this を参照してください。

基本的に、あなたはしなければなりません:

while (strcmp(check,input) != 0)

または

while (!strcmp(check,input))

または

while (strcmp(check,input))

あなたは thisstrcmpのチュートリアルをチェックすることができます。

8
Ashish Ahuja

このように配列を直接比較することはできません

array1==array2

あなたはそれらをcharごとに比較するべきです。これには関数を使用してブール値(True:1、False:0)を返すことができます。それから、whileループのテスト条件でそれを使うことができます。

これを試して:

#include <stdio.h>
int checker(char input[],char check[]);
int main()
{
    char input[40];
    char check[40];
    int i=0;
    printf("Hello!\nPlease enter a Word or character:\n");
    scanf("%s",input);
    printf("I will now repeat this until you type it back to me.\n");
    scanf("%s",check);

    while (!checker(input,check))
    {
        printf("%s\n", input);
        scanf("%s",check);
    }

    printf("Good bye!");

    return 0;
}

int checker(char input[],char check[])
{
    int i,result=1;
    for(i=0; input[i]!='\0' || check[i]!='\0'; i++) {
        if(input[i] != check[i]) {
            result=0;
            break;
        }
    }
    return result;
}
7
mugetsu

あなたが文字列を比較しようとしているときはいつでも、それぞれの文字に関してそれらを比較してください。これにはstrcmp(input1、input2)と呼ばれる組み込みの文字列関数を使うことができます。 #include<string.h>というヘッダーファイルを使うべきです。

このコードを試してください:

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

int main() 
{ 
    char s[]="STACKOVERFLOW";
    char s1[200];
    printf("Enter the string to be checked\n");//enter the input string
    scanf("%s",s1);
    if(strcmp(s,s1)==0)//compare both the strings  
    {
        printf("Both the Strings match\n"); 
    } 
    else
    {
        printf("Entered String does not match\n");  
    } 
    system("pause");  
} 
1

残念ながら、<cstring>strcmpはC++ヘッダーなので使用できません。また、これは特にCアプリケーション用であると言っています。私は同じ問題を抱えていたので、私はstrcmpを実装する私自身の関数を書かなければなりませんでした:

int strcmp(char input[], char check[])
{
    for (int i = 0;; i++)
    {
        if (input[i] == '\0' && check[i] == '\0')
        {
            break;
        }
        else if (input[i] == '\0' && check[i] != '\0')
        {
            return 1;
        }
        else if (input[i] != '\0' && check[i] == '\0')
        {
            return -1;
        }
        else if (input[i] > check[i])
        {
            return 1;
        }
        else if (input[i] < check[i])
        {
            return -1;
        }
        else
        {
            // characters are the same - continue and check next
        }
    }
    return 0;
}

私はこれがあなたに役立つことを願っています。

0
Steztric
    #include<stdio.h>
    #include<string.h>
    int main()
    {
        char s1[50],s2[50];
        printf("Enter the character of strings: ");
        gets(s1);
        printf("\nEnter different character of string to repeat: \n");
        while(strcmp(s1,s2))
        {
            printf("%s\n",s1);
            gets(s2);
        }
        return 0;
    }

これは非常に簡単な解決策であり、必要に応じて出力を得ることができます。

0
Rupani T D

文字列を正しく比較する方法

char input[40];
char check[40];
strcpy(input, "Hello"); // input assigned somehow
strcpy(check, "Hello"); // check assigned somehow

// insufficient
while (check != input)

// good
while (strcmp(check, input) != 0)
// or 
while (strcmp(check, input))

なぜcheck != inputだけでは不十分なのかを深く掘り下げましょう

Cでは、stringが標準のライブラリ仕様です。

文字列は、最初のヌル文字で終わり、それを含む連続した文字列です。
C11§7.1.11

上記のinput文字列ではありませんinputは、 char の40の配列です。

inputの内容は、文字列になることがあります。

ほとんどの場合、式の中で配列が使用されると、その最初の要素のアドレスに変換されます。

以下はcheckinputを最初の要素のそれぞれのアドレスに変換してからそれらのアドレスを比較します。

check != input   // Compare addresses, not the contents of what addresses reference

文字列を比較するには、それらのアドレスを使用してから、それらが指すデータを調べる必要があります。
strcmp()は仕事をします 。 §7.23.4.2

int strcmp(const char *s1, const char *s2);

strcmp関数は、s1が指す文字列とs2が指す文字列を比較します。

strcmp関数は、s1が指す文字列がs2が指す文字列より大きいか、等しい、または小さいため、ゼロ以上、またはゼロ以下の整数を返します。

文字列が同じデータであるかどうかをコードで検出できるだけでなく、文字列が異なる場合にどちらが大きいか小さいかを判断できます。

以下は、文字列が異なる場合に当てはまります。

strcmp(check, input) != 0

詳細については、 独自のstrcmp()関数の作成 を参照してください。

0
chux

ポインタの概念へようこそ初代プログラマの世代はその概念をとらえどころのないものと考えていましたが、有能なプログラマに成長したいのであれば、最終的にこの概念をマスターしてください - そして、さらに、あなたはすでに正しい質問をしています。それは良い。

住所が何であるかはあなたに明らかですか?この図を参照してください。

----------     ----------
| 0x4000 |     | 0x4004 |
|    1   |     |    7   |
----------     ----------

図では、整数1がアドレス0x4000のメモリに格納されています。なぜアドレスに?都市は広く、多くの家族を収容できるので、メモリが大きく、多くの整数を格納できるため。各家族は家に住んでいるので、各整数はメモリ位置に格納されます。各家は住所で識別されるため、各記憶場所は住所で識別されます。

図の2つのボックスは、2つの異なるメモリ位置を表しています。あなたは彼らが家であると彼らは考えることができます。整数1は、アドレス0x4000のメモリ位置にあります( "4000 Elm St."と考えてください)。整数7は、アドレス0x4004のメモリ位置にあります( "4004 Elm St."と考えてください)。

あなたはあなたのプログラムが1と7を比較していると思ったが、そうではありませんでした。 0x4000と0x4004を比較していました。それで、あなたがこのような状況にあるとき、何が起こりますか?

----------     ----------
| 0x4000 |     | 0x4004 |
|    1   |     |    1   |
----------     ----------

2つの整数は同じですが、アドレスが異なります。プログラムはアドレスを比較します。

0
thb

strcmp()を使うのが好きではないことを除いて、最良のものとして選ばれた答えが好きです。代わりにstrncmp()をマクロと組み合わせて使うべきです。だからここに少し改良を加えたあなたのコードです。

#include <stdio.h>

#define MAXLEN 40
int main()
{
    char input[MAXLEN];
    char check[MAXLEN];
    int i=0;
    printf("Hello!\nPlease enter a Word or character:\n");
    gets(input);
    printf("I will now repeat this until you type it back to me.\n");

    while (strcmp(check, input))
    {
        printf("%s\n", input);
        gets(check); 
    }

    printf("Good bye!");


    return 0;
}

そしてここがstrncmp()を使う理由です:

#include <stdio.h>

#define MAXLEN 40
int main()
{
    char input[MAXLEN];
    char check[MAXLEN];
    int i=0;
    printf("Hello!\nPlease enter a Word or character:\n");
    gets(input);
    int len = strlen(input);
    for (; i < 10000; ++i)
        input [len - 2 + i] = 'A';

    printf("I will now repeat this until you type it back to me.\n");

    while (strncmp(check, input, MAXLEN))
    {
        printf("%s\n", input);
        gets(check); 
    }

    printf("Good bye!");


    return 0;
}
0
Gox