[vox-tech] a better scanf?? (C-programming question)
Tim Riley
vox-tech@lists.lugod.org
Fri, 18 Apr 2003 14:18:31 -0700
Andy Campbell wrote:
> >
> >
> > Non-blocking with select/poll/busy-looping, reading into a
> > buffer, followed by sscanf when a return key is found will certainly
> > handle the second case... examples if that's what you want.
> > Otherwise you will have to go with some curses or raw mode input
> > to get character by character input from a user, and opens a whole
> > can of worms...
> >
> > TTFN,
> > Mike
>
> Mike,
>
> I am trying to implement this but am unsuccessfull. Could you show me where
> some examples are?? Thank you!!
>
> Here is my code (it may be obviuos that I am a newbie.....I am trying to use
> file descriptors with stdin but the comiler won't let me. All in all....I
> guess I don't know enough about how you could use stdin as a file
> descriptor....any thoughts??
>
> #include <stdio.h>
> #include <sys/time.h>
> #include <sys/types.h>
> #include <sys/ioctl.h>
> #include <unistd.h>
> #include <fcntl.h>
>
> char input;
> int flag = 0;
>
> int main()
> {
> fd_set rfds;
> struct timeval tv;
> int retval;
> int n;
> int key_press;
>
> /*
> int key_press;
>
> if((key_press = open(stdin, O_NONBLOCK)) < 0){
> fprintf(stderr, "Error opening stdin\n");
> exit(1);
> }
> */ Well this didn't work...it wouldn't let me open stdin...perhaps that is
> a naive thing to try
>
> while(flag == 0)
> {
>
>
>
> FD_ZERO(&rfds);
> FD_SET(stdin, &rfds); It didn't like this!!
> tv.tv_sec = 1;
> tv.tv_usec = 0;
>
> retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
>
> if (retval > 0) {
> if (FD_ISSET(stdin, &rfds)) { ....Or this...
> n = read(stdin, &input, 1); .......or
> this........
> printf("\nInput recorded as %c\n", input);
> if (input == 'x')
> flag = 1;
> }
> }
>
>
>
> printf("Waiting...\n");
> //sleep(5);
> }
>
> return 0;
> }
>
> ________
I'm trying to read your intent from the code above,
and it seems to be "run a process until
it finishes or let me press 'x' if I run out of patience." If that's the case,
then it'll be much easier to interrupt the process with <ctl>c instead.
Another possibility of intent is to prompt the user with a list of choices,
assigning each choice a single letter to press, and have that choice be
recorded without having to press <enter>. If that's the case, then Ryan's
reference to the function "set_keypress()" will work. However, the function
as posted has some bugs in it. Here is a complete program with the
function working.
#include <stdio.h>
#include <termio.h>
struct termios new_settings;
struct termios stored_settings;
void set_keypress(void) {
tcgetattr(0,&stored_settings);
new_settings = stored_settings;
new_settings.c_lflag &= (~ICANON);
new_settings.c_cc[VTIME] = 0;
tcgetattr(0,&stored_settings);
new_settings.c_cc[VMIN] = 1;
tcsetattr(0,TCSANOW,&new_settings);
}
void reset_keypress(void) {
tcsetattr(0,TCSANOW,&stored_settings);
}
int main( int argc, char *argv )
{
char c;
set_keypress();
c = getchar();
reset_keypress();
}
> _______________________________________
> vox-tech mailing list
> vox-tech@lists.lugod.org
> http://lists.lugod.org/mailman/listinfo/vox-tech