69,369
社区成员
发帖
与我相关
我的任务
分享
/* play_again3.c
* purpose: ask if user wants another transaction
* method: set tty into chr-by-chr, no-echo mode
* set tty into no-delay mode
* read char, return result
* returns: 0=>yes, 1=>no, 2=>timeout
* better: reset terminal mode on Interrupt
*/
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#define ASK "Do you want another transaction"
#define TRIES 3 /* max tries */
#define BEEP putchar('\a') /* alert user */
main()
{
int response;
tty_mode(0); /* save current mode */
set_cr_noecho_mode(); /* set -icanon, -echo */
response = get_response(ASK, TRIES); /* get some answer */
tty_mode(1); /* restore orig mode */
return response;
}
get_response( char *question , int maxtries)
{
int input;
printf("%s (y/n)?", question); /* ask */
fflush(stdout); /* force output */
while ( 1 ){
input = tolower(get_ok_char()); /* get next chr */
if ( input == 'y' )
return 0;
if ( input == 'n' )
return 1;
if ( maxtries-- == 0 ) /* outatime? */
return 2; /* sayso */
BEEP;perror("\nHello?\n");
}
}
get_ok_char()
{
int c;
while( ( c = getchar() ) != EOF && strchr("yYnN",c) == NULL )
;
return c;
}
set_cr_noecho_mode()
{
struct termios ttystate;
tcgetattr( 0, &ttystate); /* read curr. setting */
ttystate.c_lflag &= ~ICANON; /* no buffering */
ttystate.c_lflag &= ~ECHO; /* no echo either */
ttystate.c_cc[VMIN] = 1; /* get 1 char at a time */
ttystate.c_cc[VTIME] = 20;
tcsetattr( 0 , TCSANOW, &ttystate); /* install settings */
}
set_nodelay_mode()
{
int termflags;
termflags = fcntl(0, F_GETFL); /* read curr. settings */
termflags |= O_NDELAY; /* flip on nodelay bit */
fcntl(0, F_SETFL, termflags); /* and install 'em */
}
tty_mode(int how)
{
static struct termios original_mode;
if ( how == 0 )
tcgetattr(0, &original_mode);
else
tcsetattr(0, TCSANOW, &original_mode);
}
[Quote=引用 6 楼 zhao4zhong1 的回复:]
get_ok_char()
{
int c;
fflush(stdin);//加这句
while( ( c = getchar() ) != EOF && strchr("yYnN",c) == NULL )
;
return c;
}
[/Quote]
stupid mother fucker, fflush can't be used on input stream.
this is undefined behavior:
— The stream for the fflush function points to an input stream or to an update stream
in which the most recent operation was input (7.21.5.2).
/* clreol - removes all characters from a stream up to and including
* the next newline character. If the end of the stream is encountered,
* this function returns 1. Otherwise it returns 0.
* Richard Heathfield May 15 2007, 4:57 pm
*/
#include <stdio.h>
int clreol(FILE *fp)
{
int ch;
while((ch = getc(fp)) != EOF && ch != '\n')
{
continue;
}
return ch == EOF;
}