selectによるstdin入力の傍受

3006 ワード

私はこの2,3日viのソースコード(linuxの上のvi)を研究して、今学期のカリキュラム設計で簡単なテキストエディタを書くつもりです.viソースコードではselectを利用して入力内容があるかどうかを傍受していることに気づいた.
ファイル記述子
linuxには万物がファイルされていることを知っています.すべてのファイル記述子には0、1の2つの特殊な存在があります.
実はstdin==0,stdout==1
したがって、0をselectが傍受するファイル記述子(ソケット)に設定できます.
マスクエコー
Windowsには1つの関数getch()があります(この関数は淘汰されたと言われたことは一度もありませんが、役に立つと思います).この関数の役割はキーボード入力の内容を直接読み取ることです.画面には出力(エコー)は必要ありませんが、linuxにはこの関数はありません(標準ライブラリ関数ではないことがわかります)、自分で設定する必要があります.
ヘッダファイル:termios.h
//     
    struct termios term_orig, term_vi;
    tcgetattr(0, &term_orig);
	term_vi = term_orig;
	term_vi.c_lflag &= (~ICANON & ~ECHO);	// leave ISIG ON- allow intr's
	term_vi.c_iflag &= (~IXON & ~ICRNL);
	term_vi.c_oflag &= (~ONLCR);
#ifndef linux
	term_vi.c_cc[VMIN] = 1;
	term_vi.c_cc[VTIME] = 0;
#endif
	tcsetattr(0, TCSANOW, &term_vi);
上記の文を実行すると、入力されたエコーは禁止されますが、これを行うと問題が解決できません.それは、リターン時に前の行の最後の文字の後ろに行頭を位置決めすることです.つまり、改行ですが、トップはありません.少しhtmlの中でdivにfloat:left属性を設定した後にclearのような効果はありません.
カーソルの位置
上記の問題が発生した後、私の解決方法はカーソルの位置を直接移動することであり、windowsにはAPI関数があり、カーソルの位置を直接移動することができ、linuxでは特殊な制御文字を通じています.
例えばprintf("033[3;3 H");
この文を実行すると、カーソルは画面の3行目、3列目の位置に移動します.注意すべきは033[3:3 Hのあれはセミコロンで、コロンではありません
ソースコード
/*********************************************************
 * Author           : crazy_mad
 * Last modified    : 2016-12-20 19:12
 * Filename         : main.cpp
 * Description      :   select         
 *********************************************************/

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 

using namespace std;

int main(int argc, char* argv[])
{
    char buf[256];

    //     
    struct termios term_orig, term_vi;
    tcgetattr(0, &term_orig);
	term_vi = term_orig;
	term_vi.c_lflag &= (~ICANON & ~ECHO);	// leave ISIG ON- allow intr's
	term_vi.c_iflag &= (~IXON & ~ICRNL);
	term_vi.c_oflag &= (~ONLCR);
#ifndef linux
	term_vi.c_cc[VMIN] = 1;
	term_vi.c_cc[VTIME] = 0;
#endif
	tcsetattr(0, TCSANOW, &term_vi);

    fd_set readfd;
    struct timeval tv;
    //struct input_event event_kb;
    FD_ZERO(&readfd);
    FD_SET(0, &readfd);
    tv.tv_sec = 0;
    tv.tv_usec = 50000;
    while (select(0, &readfd, NULL, NULL, &tv) >= 0) {
        int i = read(0, buf, sizeof(buf));
        buf[i] = 0;
        if (i > 0) {
            //printf("%c
", buf[0]); write(1, buf, strlen(buf)); } if (buf[0] == 'q') { break; } } strcpy(buf, "\033[4;0Haaaa"); write(1, buf, strlen(buf)); tcsetattr(0, TCSANOW, &term_orig); return 0; }