ユーザーに単語や文字を入力させ、それを保存してから、ユーザーがもう一度入力するまで印刷してプログラムを終了させるプログラムを作成しようとしています。私のコードはこのようになります:
#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つを間違って比較していますか?
!=
や==
を使って文字列を(便利に)比較することはできません。strcmp
を使う必要があります。
while (strcmp(check,input) != 0)
これは、!=
と==
がこれらの文字列のベースアドレスのみを比較するためです。文字列自体の内容ではありません。
念のために言っておきますが、gets
は安全ではないため、バッファオーバーフローが発生しないようにfgets(input, sizeof(input), stdin)
に置き換えてください。
次に、文字列を比較するには、strcmp
を使用する必要があります。戻り値0は、2つの文字列が一致することを示します。等号演算子(つまり!=
)を使用すると、2つの文字列のアドレスが比較されます(それぞれの中の個々のchar
sとは対照的です)。
また、この例では問題は発生しませんが、fgets
は改行文字'\n'
をバッファにも格納します。 gets()
は違います。 fgets()
からのユーザ入力を"abc"
のような文字列リテラルと比較した場合、それは決して一致しません(バッファが小さすぎて'\n'
が収まらない場合を除く)。
編集:そして再び超高速神秘主義者によって殴ら。
このように配列を直接比較することはできません
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;
}
あなたが文字列を比較しようとしているときはいつでも、それぞれの文字に関してそれらを比較してください。これには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");
}
残念ながら、<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;
}
私はこれがあなたに役立つことを願っています。
#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;
}
これは非常に簡単な解決策であり、必要に応じて出力を得ることができます。
文字列を正しく比較する方法
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
の内容は、文字列になることがあります。
ほとんどの場合、式の中で配列が使用されると、その最初の要素のアドレスに変換されます。
以下はcheck
とinput
を最初の要素のそれぞれのアドレスに変換してからそれらのアドレスを比較します。
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()
関数の作成 を参照してください。
ポインタの概念へようこそ初代プログラマの世代はその概念をとらえどころのないものと考えていましたが、有能なプログラマに成長したいのであれば、最終的にこの概念をマスターしてください - そして、さらに、あなたはすでに正しい質問をしています。それは良い。
住所が何であるかはあなたに明らかですか?この図を参照してください。
---------- ----------
| 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つの整数は同じですが、アドレスが異なります。プログラムはアドレスを比較します。
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;
}