C++で改行を待たずに標準入力から1文字ずつ読み取る方法
C++でキーが押された瞬間に検知し、改行(Enterキー)を待たずに標準入力から1文字ずつ読み取る処理は、標準ライブラリだけでは移植性の高い形で実現できません。OSごとに異なる手法を使う必要があります。
本記事では、WindowsとUNIX系OSそれぞれの環境で、Enterキーを待たずに入力文字を取得する方法をコード例とともに解説します。
Windowsの場合:conio.hのgetch()関数を使う
Windowsでは、コンソール入出力用のconioライブラリにあるgetch()関数を使用すると、ユーザーが押したキーをリアルタイムに取得できます。
サンプルコード
#include<iostream>
#include<conio.h>
using namespace std;
int main() {
char c;
while(1) { // 無限ループ
c = getch();
cout << c;
}
}
このプログラムは、入力された文字をそのままターミナルへ出力し続けます。なお、conioライブラリはWindows専用のため、このコードはWindows環境でのみ動作します。
UNIX系OSの場合:端末をrawモードに変更する
LinuxやmacOSなどのUNIX系OSでは、sttyコマンドで端末を「rawモード」に切り替えることで、同様の動作を実現できます。通常、端末は行単位で入力をバッファリングしていますが、rawモードではこのバッファリングが無効になり、キーが押された瞬間に文字を受け取れるようになります。
サンプルコード
#include<iostream>
#include<stdio.h>
int main() {
char c;
// 端末をrawモードに設定
system("stty raw");
while(1) {
c = getchar();
// 「.」が押されたら終了
if(c == '.') {
system("stty cooked");
exit(0);
}
std::cout << c << " was pressed."<< std::endl;
}
}
この例では、まずstty rawで端末をrawモードに切り替えてからgetchar()で1文字ずつ読み取ります。「.」(ピリオド)が入力されると、stty cookedで端末を通常のcookedモードに戻してからプログラムを終了します。
rawモードのままプログラムを終了すると、シェルが正常に操作できなくなることがあるため、終了前に必ずモードを元に戻すのが重要なポイントです。
まとめ
- Windows:conio.hの
getch()関数でキー入力を即座に取得できる - UNIX系OS:
sttyコマンドでrawモードに切り替えてからgetchar()を使う - 注意点:rawモード使用後は必ずcookedモードへ戻す
より堅牢な実装が必要な場合は、UNIX系ではtermios構造体を直接操作する方法や、ncursesなどのライブラリを活用するのもおすすめです。
-
C++でヘッドポインタなしに片方向連結リストからノードを削除する方法
このチュートリアルでは、片方向連結リスト(シングルリンクリスト)において、ヘッドポインタなしでノードを削除する方法を解説します。通常、連結リストからノードを削除するには、削除対象ノードの直前のノードへのポインタが必要です。しかし、ヘッドポインタが渡されていない場合、前のノードをたどってたどり着くことができません。そこで役立つのが「次のノードのデータをコピーする」というテクニックです。解決の手順データ(data)と次ノードへのポインタ(next)を持つ構造体を定義する片方向連結リストにノードを挿入する関数を実装するダミーデータを使って連結リストを初期化するnextポインタを使って、削除対象ノード
-
【C++】L = {aⁿbᵐaⁿ⁺ᵐ}(n, m ≥ 1)を受理するチューリングマシンの構築方法
チューリングマシン(Turing Machine)とは チューリングマシンは、0型文法(タイプ0文法)から生成される言語の語を受理するために用いられる装置です。チューリングマシン(TM)は、セルに区切られた無限長のテープからなる数学的モデルであり、このテープに入力が与えられます。TMは入力テープを読み取るヘッドを備え、状態レジスタがマシンの現在の状態を保持します。入力記号を読み込むと、その記号は別の記号に置き換えられ、内部状態が変化し、ヘッドは左右いずれかのセルへ移動します。TMが最終状態に到達すれば入力文字列は受理され、到達できなければ拒否されます。 TMは次の7つ組(Q, X, Σ, δ,