googleの窓にアバウトな質問を投げるとAIが答えてくれるので便利な世の中です.
「linuxのC言語でKBDから1文字づつ入力してstringに連結して"\n"で終了するcode」
でもgetchar()だとKeyが押されるまでブロッキングされちゃいますね.
周期的に動く別の仕事があるのでそっちはthreadでやればいいんだけど、getchar()でmain()がブロックされるのはチト困るんだが・・・ getchar()ってブロッキング関数なうえにtimeout無いから行ったきりで嫌なんだなぁ.
そこで再びAIに聞きました.
「linuxでKBDから1文字入力のブロッキングしないやり方」
AIは答えてくれますが、STDINをノンブロッキングに変更するのが回答でした.
へぇ~意外と面倒なんですねぇ.ノンブロックのgetchar()類似関数があるのかと思ってたんだけどそうじゃなかった....
↓AIのお答え
// 1. 端末をカノニカルモードから非カノニカルモードへ変更(Enterなしで読み込むため)
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO); // エコー(入力文字の表示)もオフにする
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
// 2. 標準入力を非ブロッキングに設定
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
なんだなんだぁ? 2手間もかかんの?
でも動いたみたいよ.
ナイスざぁます >AI
かしこ
murasaki
返信削除AIは神ですねー。
でも、なんか副作用がありそうな方法ですね・・。
killした後でbashのKBD動作が変わるみたい
削除本当はkillの前に元に戻すべきなんだろうけどめんどくさ
murasaki
削除手軽にやろうとするといろいろ厄介ごと抱え込むし、少し普通と違うことしようとすると結構Linuxって牙をむいてくるイメージ。
unix時代からの1文字入出力という超シンプル思考がLinuxでもまだ生きている感じですね。
キーコードをデバイスから直接読むやり方が組込みっぽいかもですね。面倒ですが。
linuxで有難いのは、
削除探せば情報があるとこかな
windowsは非公開だから困ったときにわからんくて
「fgetc(stdin) ノンブロック」でAI検索したら、こんな回答が・・・
返信削除方法1:fcntl を使って stdin をノンブロッキングにする (POSIX準拠, Linux/macOS)
※↑ と同じやり方
方法2:select() または poll() で入力チェックする
fgetc を使う前に、select 関数で stdin にデータが届いているか確認します。データがない場合は fgetc を呼ばないことで、ブロッキングを回避します。
#include
#include
#include
int is_stdin_ready() {
struct timeval tv = {0, 0};
fd_set fds;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
// タイムアウトを0にして即座にチェック
return select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv) > 0;
}
int main() {
printf("文字を入力: ");
while (1) {
if (is_stdin_ready()) {
int c = fgetc(stdin);
if (c == 'q') break;
printf("入力: %c\n", c);
}
// 他の処理をここで行う
}
return 0;
}
※「select 関数」なんて、あるの知らなかったわ。
方法3:ncurses ライブラリを使用する (推奨)
ターミナル入力を制御する標準的なライブラリである ncurses を使うのが最も簡単で確実です。nodelay(stdscr, TRUE) を設定すると、getch() がノンブロッキングになります。
※「ncurses ライブラリ」って、よく聞くけど、こういう時に使うのか。
注意点
・カノニカルモード: デフォルトのターミナルは1行単位で入力を待つ(カノニカルモード)ため、1文字ずつノンブロックで読み込むには、上記の termios 設定や ncurses を使ってターミナルを raw/cbreak モードにする必要があります。
・CPU負荷: ノンブロッキングループ内でスリープ(usleep)を入れないと、データがない間、CPUを100%使用してしまうため注意が必要です。
※まぁ、そうだよね。C は「低級言語」なので、この辺もちゃんと面倒見ないといけないですね。