2019/04/21

[c/c++]きっちり3文字だけ入力したことを確認する

C/C++を使って長いものの、標準出力とか標準入力には、疎い。
特に、標準入力は使う機会がほとんどなかったので、あまり理解していない。


さて、今、Linuxで標準入力から文字を入力させ、その内容をチェックして処理を進める、ということをやろうとしている。
"YES"と入力した場合だけ進める、ということにしよう。


まずはシンプルに。

01: #include <stdio.h>
02: #include <string.h>
03: 
04: int main(void)
05: {
06:     char prompt[20];
07:     scanf("%s", prompt);
08:     if (strcmp(prompt, "YES") == 0) {
09:         printf("YES !\n");
10:     } else {
11:         printf("no\n");
12:     }
13:     return 0;
14: }

問題点は、大きく2つ。

  • スペースが入ると、その前までしか評価されない
  • バッファサイズよりも大きい文字列が入力できてしまう


前者は、たとえば"YES ?"のように半角スペースを間に挟むと、その手前までしか評価されないということだ。
これはどちらかというと、bashとかそういう環境に依存しているんじゃなかろうか。

後者は、"YESSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"なんて入力すると、バッファが20しかないので死んでしまう、というやつだ。
%sの方でしばることもできるが、何にせよ前者の方が対処できない。


調べてみると、fgets()で標準入力を取り込む作戦がよく出てきた。

ただ、このfgets()、改行コードもそのまま取り込むようだ。
strlen()で\0の前に改行コードがあるはず、という前提にしようかと思ったが、それなら改行コード込みでmemcmp()でもいいんじゃなかろうか。

01: #include <stdio.h>
02: #include <string.h>
03: 
04: int main(void)
05: {
06:     char prompt[5];
07:     fgets(prompt, sizeof(prompt), stdin);
08:     if (memcmp(prompt, "YES\n", 4) == 0) {
09:         printf("YES !\n");
10:     } else {
11:         printf("no\n");
12:     }
13:     return 0;
14: }

まあ、4を直接書くのは嫌だから、YESの文字列をマクロにしてsizoef()-1するとかか。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。