Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
890 views
in Technique[技术] by (71.8m points)

c - raw terminal mode - how to take in input?

I have a chat client that takes in input in raw terminal mode, but I don't know about handling input in this mode. I need to know 2 things:

  • How can I read the input in character-by-character and display it? Do I have to have some sort of a read loop that reads one character at a time and stores it in a buffer?
  • If I want my server to process the input on new line entry, do I have to scan each character as it comes into my buffer and look for ?

Also, an example character-by-character read loop that flushes on would be really great to see. Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In Windows there is a very useful function kbhit() but that is not there in linux unfortunately. There can be multiple methods for this. we'll make our own kbhit() method for linux. kbhit() will return non zero value when something is detected in the input buffer otherwise it will return 0 and pass on. In simple words it is non-blocking. Whenever the result is true then call getch() method to fetch that pressed key.

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>

void changemode(int);
int  kbhit(void);
int main(void)
{
  int ch;
  changemode(1);
  while ( !kbhit() );      // Waiting for some keyboard input.

  // something has been detected. now get that.
  ch = getchar();

  printf("
Got %c
", ch);

  changemode(0);
  return 0;
}

void changemode(int dir)
{
  static struct termios oldt, newt;

  if ( dir == 1 )
  {
    tcgetattr( STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);
  }
  else
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
}

int kbhit (void) 
{
  struct timeval tv;
  fd_set rdfs;

  tv.tv_sec = 0;
  tv.tv_usec = 0;

  FD_ZERO(&rdfs);
  FD_SET (STDIN_FILENO, &rdfs);

  select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
  return FD_ISSET(STDIN_FILENO, &rdfs);

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...