【C++】キーボード入力を取得するgetchとgetchar関数
- 作成日:2024/10/20
- 更新日:2018/10/24
標準入力のcinを使わずにキーボードからの入力を取得する方法です。
getchとgetchar関数とは
どちらもキーボードからの入力を「1文字」取得する関数です。 取得するのは1文字なので、複数の文字を取得したい場合はループ処理が必須です。
getchとgetcharの違い
大きく2つの違いがあります。
1つ目は、文字の取得時のちがいです。 getcharは入力し終えたらEnterキーを押下することで文字を取得しますが、 getchは入力した瞬間に文字を取得します。
2つ目は、表示方法のちがいです。 getcharは入力したらその文字がコンソールに出力されますが、 getchは出力されません。
どっちを使う?
どちらを利用するかはケースバイケースですが、押下した瞬間に処理したい場合や、 コンソールに入力したものを出力させたくない場合はgetchが良いでしょう。
一方で、入力したものがわかるようにしておきたい場合はgetcharを使いましょう。
使い方
サンプルを用いて使い方を紹介します。
getch関数
以下のコードは1文字を取得する例です。
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
char ch = getch();
cout << "入力したもの:" << ch << endl;
return 0;
}
キーボードで「a」と入力した瞬間、以下のような結果が表示されます。
入力したもの:a
getchar関数
以下のコードも1文字を取得する例です。
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
char ch = getchar();
cout << "入力したもの:" << ch << endl;
return 0;
}
キーボードで「a」と入力してEnterキーを押下すると、以下のような結果が表示されます。
入力したもの:a
getchと違い、入力値がコンソールに出力されるのがわかるでしょう。
複数の文字を取得する
少し応用です。getchを使い複数の文字を取得してみましょう。 適当な文字列を入力してTabキー押下時に入力したものを出力する例です。
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
int main()
{
string tmp;
char ch;
while (1)
{
//1文字取得
ch = getch();
//文字連結
tmp = tmp + ch;
//Tabキーが押下された場合
if (GetAsyncKeyState(VK_TAB))
{
break;
}
}
cout << "入力したもの:" << tmp << endl;
return 0;
}
キーボードで「abcdef」と入力してTabキーを押下すると、以下のような結果が表示されます。
入力したもの:abcdef
15行目で1文字取得し、それを文字列tmpに格納しています。 キーが押下されたかどうかはGetAsyncKeyState関数を使います。 今回は引数にTabを指定していますね。
Tabが押下されるまでは文字の取得・連結を繰り返すコードになっています。
ちなみに、getcharだとEnterキーを押下しないと文字取得ができないため、 このサンプルではうまく動かないのでご注意ください。
バックスペースによる再入力について
getchは入力したキーが全て取得されるので、入力のやり直しは注意が必要です。
例えば、abcと入力するのに誤ってabbと入力したとします。1文字消すためにバックスペースを押下してcを入力したいところですが、 プログラム的には「a b b \b c」となるのです。\bはバックスペースです。
cout関数で出力するだけならコンピュータが気を利かせてバックスペースの前の文字を削除して出力してくれるので問題なさそうに見えますが、 取得した文字列を1文字ずつ判別したい場合などは注意が必要です。
以下のサンプルだと違いがわかるでしょう。
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
int main()
{
string tmp;
char ch = '\n';
while (1)
{
// 1文字取得
ch = getch();
// 文字連結
tmp = tmp + ch;
// Tabキーが押下された場合
if (GetAsyncKeyState(VK_RETURN))
{
break;
}
}
cout << "coutで全部出力\n" << tmp << endl;
cout << "coutで1文字ずつ出力"<< endl;
for (int i = 0; i < tmp.length() - 1; i++)
{
cout << tmp[i] << endl;
}
return 0;
}
コンソールで「a b b バックスペース c」と入力すると以下の結果になります。
coutで全部出力
abc
coutで1文字ずつ出力
a
b
b
c
配列の中身を1文字ずつ改行して出力すると入力し直す前のbやバックスペースが格納されているのがわかります。
「abc」という文字列だと思っていたら、実は中身は「abb\bc」だったというわけです。 このように、getchでバックスペースを使う場合はご注意ください。
getch関数が使えない?
端的に書きますが、私の環境ですとeclipceのコンソールだとgetchがうまく動作しませんでした。 他の環境は未調査ですが、VSCだと正常に機能したのでgetchが使えない場合は別の開発環境を試してみると良いでしょう。