終端控制——如何在不輸入回車讀入字元

誰不小心的發表於2013-09-26

摘要:一般情況下,我們在終端輸入一些字元,輸入的同時可以編輯(增加,刪除,修改),然後輸入回車,這些字元被送到緩衝區。但是,在more程式和其他的程式中,比如遊戲中的快捷鍵,我們需要的是不用輸入回車就可以讀取字元。此時,我們就需要了解如何控制終端,使得在不輸入回車的情況下就可以讀入字元。


首先,我們看一下這個程式的實現:

 

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/ioctl.h>
int kbhit();
int main(int argc, char *argv[])
{
  int i=0;
  int c=' ';
  system("stty raw -echo");
  printf("enter q to quit\n");
  for (;  c!='q';i++)
  {
    if (kbhit())
    {   
      c=getchar();
      printf("\n got %c, on iteration %d",c,i);
    }   
  }
  system("stty cooked echo");
  return 0;
}
int kbhit()
{
  int i;
  ioctl(0,FIONREAD,&i);
  return i;
}

解析:

system:呼叫shell來執行相關命令

stty raw:將終端設定為阻塞模式,實現實時讀取

ioctl:查詢鍵盤緩衝區狀態

函式名: ioctl
標頭檔案:#include<sys/ioctl.h>
功 能: 控制I/O裝置 ,提供了一種獲得裝置資訊和向裝置傳送控制引數的手段。用於向裝置發控制和配置命令 ,有些命令需要控制引數,這些資料是不能用read / write 讀寫的,稱為Out-of-band資料。也就是說,read / write 讀寫的資料是in-band資料,是I/O操作的主體,而ioctl 命令傳送的是控制資訊,其中的資料是輔助的資料。
用 法: int ioctl(int handle, int cmd,[int *argdx, int argcx]);
返回值:成功為0,出錯為-1
FIONREAD : 通過由ioctl的第三個引數指向的整數返回當前在本套介面接收緩衝區中的位元組數。本特性同樣適用於檔案,管道和終端。

相關文章