ページ 11

文字列の比較。

Posted: 2015年2月02日(月) 23:37
by aaaww
//This prog is simple check algrithm.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>

int main(int argc, char** argv){

char id[20] = "root",eid[20];
while (1){
printf("Enter id:");
scanf_s("%s", eid);

if (strcmp(id, eid) == 0){
printf("Congratz.\n");
}
else{
printf("Wrong.\n");
}
}
return 0;
}

このようなidを比較するプログラムを書いたのですが、入力した文字が一致していてもWrong.と出ます。
そしてなぜかなんども

Enter id:Wrong.
Enter id:Wrong.
Enter id:Wrong.
Enter id:Wrong.
と出ます。
なぜ、このようになるのか、改善策を教えてください。

Re: 文字列の比較。

Posted: 2015年2月02日(月) 23:53
by a5ua
scanf_s()の使い方が間違っています。
scanf_sで文字列を入力するときは、可変長引数部分にポインタだけでなくバッファサイズを渡す必要があります。

以下のURLも参照してください。
https://msdn.microsoft.com/ja-jp/library/w40768et.aspx
scanf および wscanf とは異なり、scanf_s および wscanf_s では、c、C、s、S の各型、または [] で囲まれた文字列コントロール セットのすべての入力パラメーターに対してバッファー サイズを指定する必要があります。 バッファー サイズ (文字単位) は、バッファーまたは変数のポインターの直後に追加パラメーターとして渡されます。 たとえば、文字列を読み込む場合、その文字列のバッファー サイズは次のように渡されます。

char s[10];

scanf_s("%9s", s, _countof(s)); // buffer size is 10, width specification is 9

バッファー サイズには、終端 null も含まれます。 幅指定フィールドを使用して、読み取られたトークンがバッファーに確実に収まるようにすることができます。 幅指定フィールドが使用されない場合で、読み取られたトークンがバッファーに収まらない場合、そのバッファーには何も書き込まれません。

Re: 文字列の比較。

Posted: 2015年2月02日(月) 23:54
by みけCAT
コードはBBCodeを有効にした状態でcodeタグで囲み、かつ適切にインデントをしていただけると、見やすくて助かります。
(今回のコードはreturn 0;以外の部分のインデントはよく整っています)

適当に書き換えて試したところ、Enter id:Congratz.が大量に表示されました。
大量に表示されるのは、while(1)で無限ループになっているからです。
http://melpon.org/wandbox/permlink/DCsiMMOapNejOdC6

また、scanf_sを使用する場合は、バッファの指定の後ろにその要素数を指定する必要がある可能性があります。
scan_sではなくscanfを使用するか、バッファの指定の後ろにその要素数の指定を追加すると改善するかもしれません。

Re: 文字列の比較。

Posted: 2015年2月03日(火) 00:04
by aaaaww
大変わかりやすい回答ありがとうございます。
VisualStudioにコンパイルエラーでscanf_sを使えと言われ使ったのですが、
これが原因だと思いませんでした。
先頭に
#define _CRT_SECURE_NO_WARNINGS
これを追加すること、scanfにすることにより改善できました。

次から投稿する時には、インデントなども見やすくします。