Wait only 5 second for user input - c

I want to write a simple c program in turbo c++ 4.5 editor such that in only wait 5 seconds for user input. As an example,
#include <stdio.h>
void main()
{
int value = 0;
printf("Enter a non-zero number: ");
// wait only 5 seconds for user input
scanf("%d",&value);
if(value != 0) {
printf("User input a number");
} else {
printf("User dont give input");
}
}
So, what will be the code for 5 seconds wait for 'scanf' functionality and otherwise execute if-else part.

Try a select(2) loop: https://www.mirbsd.org/man2/select on stdin (fd#0) with a timeout of 5 seconds; run the scanf(3) only if select returns indicating there is data. (See the c_read() function in the mksh source code for an example.)
Other functions, like poll(2), are also possible. Nonblocking I/O is a bit overkill.
OK, here’s a working (on MirBSD) example using select:
#include <sys/types.h>
#include <sys/time.h>
#include <err.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int
main(void)
{
int value = 0;
struct timeval tmo;
fd_set readfds;
printf("Enter a non-zero number: ");
fflush(stdout);
/* wait only 5 seconds for user input */
FD_ZERO(&readfds);
FD_SET(0, &readfds);
tmo.tv_sec = 5;
tmo.tv_usec = 0;
switch (select(1, &readfds, NULL, NULL, &tmo)) {
case -1:
err(1, "select");
break;
case 0:
printf("User dont give input");
return (1);
}
scanf("%d", &value);
if (value != 0) {
printf("User input a number");
} else {
printf("User dont give input");
}
return (0);
}
You might want to play with the exit codes a bit and sprinkle a few \n throughout the code. The fflush(stdout); is important so that the prompt is shown in the first place…

#include <stdio.h>
#include <signal.h>
void handler(int signo)
{
return;
}
int main()
{
int x;
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
alarm(5);
if (scanf("%d", &x) == 1)
{
printf("%d\n", x);
alarm(0); // cancel the alarm
}
else
{
printf("timedout\n");
}
return 0;
}

well you can use the halfdelay() function from the curses library

Related

Why simple read string from non blocking IO in C behaves oddly in loop?

I have just encountered a problem which I couldn't found the reason. The code works as Below:
There is a while loop which does a lot of stuff in the middle (Does not even written), and has a non-blocking IO to receive the end process command (which is a string).
At any time, a user could come and wants to finish the process. He/She would press some keys and then press the [Enter] button.
After select find out there is an input, it uses the input string and evaluates with the EXIT string and end the process.
Now the problem is when I use the exitFlag string as the termination key it just don't accept it and keeps writing <the printf() statement> until i hit cntrl+c.
I have tried scanf(), fputs(), fread() to recieve input string from stdin and also used fflush(stdin) and fflush(stdout) to clear the std buffers.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
fd_set s;
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
char exitFlag[10];
int sFlag;
printf("Enter \"EXIT\" to End the Process\n");
while (1)
{
fflush(stdin); fflush(stdout);
FD_ZERO(&s);
FD_SET(STDIN_FILENO, &s);
timeout.tv_sec = 3; timeout.tv_usec = 0;
sFlag = select(STDIN_FILENO+1, &s, NULL, NULL, &timeout);
printf("%d: ", sFlag);
if (sFlag < 0) _exit(0);
else if (sFlag == 0)
{
printf("-\n");
fflush(stdin); fflush(stdout);
}
else
{
fflush(stdin); fflush(stdout);
scanf("%[^\n]s", &exitFlag); // fgets( exitFlag, 10, stdin); // fread( exitFlag, 10, 1 ,stdin);
printf("You have Pressed %s, Enter \"EXIT\" to End the Process: ", exitFlag);
printf("%s\n", exitFlag);
if ( memcmp(&exitFlag, "EXIT", 4) == 0 ) break;
}
}
return 0;
}
Ironically, I don't encounter similar problem when using char as the termination key input rather than string.
I would be very thankful if someone explains where I made mistake in the IO or any other place.
I have also reviewed prior questions carefully but they had seemed to work with a single keyboard press which was not safe for common use!
include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
fd_set s;
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
char exitFlag;
int sFlag;
while (1)
{
fflush(stdout);
FD_ZERO(&s);
FD_SET(STDIN_FILENO, &s);
timeout.tv_sec = 3; timeout.tv_usec = 0;
sFlag = select(STDIN_FILENO+1, &s, NULL, NULL, &timeout);
if (sFlag < 0) _exit(0);
else if (sFlag == 0)
{
fflush(stdout);
printf("-\n");
}
else
{
fflush(stdin);
scanf("%c", &exitFlag);
printf("You have Pressed %c, Press E to exit: ", exitFlag);
printf("%c\n", exitFlag);
fflush(stdout);
if ( exitFlag =='E' ) break;
}
}
return 0;
}

How to use scanf without stopping the program C language?

I'm doing a counter where I'm showing how many seconds the user has to make the input. The problem is that when I use scanf(), the program will stop and will wait for the answer, but I don't want that. I'd like to keep running the counter even thought the user doesn't put anything.
Example:
for(int i=10;i>=0;i--){
i==0? printf("time over\n"):printf("%d seconds left\n",i);
scanf("%s", decision);
sleep(1);
}
What can i do to solve this?
Like mentioned in the comments one possibility would be to use poll.
man poll says:
poll() examines a set of file descriptors to see if some of them are
ready for I/O or if certain events have occurred on them.
In code it could look like this:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/poll.h>
#include <stdbool.h>
int main() {
struct pollfd fds[1];
fds[0].fd = STDIN_FILENO;
fds[0].events = POLLIN;
bool dataAvailable = false;
for (int i = 10; i >= 0 && !dataAvailable; i--) {
switch (poll(fds, 1, 1000)) {
case -1:
perror("poll failed");
exit(1);
case 0:
printf("%d seconds left\n", i);
break;
default:
dataAvailable = true;
}
}
if (dataAvailable) {
//read from stdin
} else {
fprintf(stderr, "no input\n");
exit(1);
}
return 0;
}

C- Program won't terminate after 30 seconds

We were asked to prompt the user to enter phrases, and continue asking them until they get the correct phrase needed, for 30 seconds. Here's what I've come up with:
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void childprocess(void)
{
int start = 30;
do
{
start--;
sleep(1);
} while (start >= 0);
printf("Time ran out!\n");
exit(EXIT_SUCCESS);
}
int main(void)
{
pid_tiChildID;/* Holds PID of current child */
char word[100] = "cat";
char input[100];
int length;
iChildID = fork();
if (0 > iChildID)
{
perror(NULL);
return 1;
}
else if (0 == iChildID)
{
childprocess();
return 0;
}
/* Parent process */
while (1)
{
fgets(input, sizeof(input), stdin);
length = strlen(input);
if (input[length - 1] == '\n')
{
--length;
input[length] = '\0';
}
if (strcmp(word, input) == 0)
break;
printf("Try again\n");
}
kill(iChildID, SIGUSR1);/* terminate repeating message */
printf("Finally!\n");
return 0;
}
The problem: after 30 seconds, it prints "Time runs out" but won't terminate. How do I terminate the program after 30 seconds? Any help?
Here, you are using fork which creates two separate processes with two different PIDs. You are killing child process but parent is still running so program just dont quit.
You could have also used pthread instead of fork with remains in same single process but what ever you are trying to achieve is simple with alarm function. You dont have to manage any other process. Just use alarm.
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void ALARMhandler(int sig)
{
printf("Time ran out!\n");
exit(EXIT_SUCCESS);
}
int main(void)
{
char word[100] = "cat";
char input[100];
size_t length;
signal(SIGALRM, ALARMhandler);
alarm(30);
while(1) {
fgets(input, sizeof(input),stdin);
length = strlen(input);
if(input[length-1] == '\n') {
--length;
input[length] = '\0';
}
if (strcmp(word,input) == 0)
break;
printf("Try again\n");
}
/* terminate repeating message */
printf("Finally!\n");
return 0;
}
Hope it helps !!

Exit a for loop if not input is entered after some time

So I want a method to controlling the amount of time the input prompt will wait for the user to enter something.
For example in the following code:
#include <stdio.h>
int main(void){
int i, value;
for (i=0;i<10;i++){
scanf(" %d", &value);
}
}
How can I make the program to break the for loop if the user doesn't enter any input after 5 seconds?
You can implement what you want using select (monitor stdin for some time to check if the input is available for reading), fgets (safely read input data to the buffer) and strtol (convert the buffer string to the long integer if possible).
Sample code is given below (check man pages e.g. to extend error handling):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char *argv[])
{
fd_set rfds;
struct timeval tv;
int i, val, retval;
char *endptr, buff[255];
for (i=0;i<10;i++){
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
if (retval == -1){
perror("select()");
exit(EXIT_FAILURE);
}
else if (retval){
/* FD_ISSET(0, &rfds) is true so input is available now. */
/* Read data from stdin using fgets. */
fgets(buff, sizeof(buff), stdin);
/* Convert data stored in the buffer to long int. */
errno = 0;
val = strtol(buff, &endptr, 10);
/* First, check for various possible errors. */
if (errno != 0 && val == 0) {
perror("strtol()");
exit(EXIT_FAILURE);
}
if (endptr == buff) {
fprintf(stderr, "No digits were found.\n");
exit(EXIT_FAILURE);
}
/* If we got here, strtol successfully parsed a number. */
printf("%d was read from stdin.\n", val);
}
else{
printf("No data within five seconds.\n");
break;
}
}
exit(EXIT_SUCCESS);
}
Here is a general purpose version of scanf, sync_scanf, witch should wait for seconds you choose or will return -2 as timeout:
int sync_scanf(time_t sec, const char *format, ...);
example:
#include <stdio.h>
#include <stdarg.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int sync_scanf(time_t sec, const char *format, ...);
int main(int argc, char **argv) {
int i;
int value;
int ret;
for (i = 0 ; i < 10 ; i++ ) {
ret = sync_scanf(3, "%d", &value);
if( ret > 0 ) {
printf("OK %d\n", value);
} else if( ret == -2 ) {
printf("3 seconds passed and you typed nothing!\n");
break;
} else {
printf("No enough arguments\n");
break;
}
}
return 0;
}
int sync_scanf(time_t sec, const char *format, ...) {
int re;
va_list arg;
fd_set readfds;
struct timeval timeout = {0};
timeout.tv_sec = sec;
FD_ZERO(&readfds);
FD_SET(0, &readfds);
re = select(1, &readfds, NULL, NULL, &timeout);
if( re == -1 ) {
perror("Error");
return -1;
}
else if( re == 0 ) {
return -2;
}
va_start(arg, format);
re = vfscanf(stdin, format, arg);
va_end(arg);
return re;
}
demo:
$ gcc -Wall sample.c
$ ./a.out
232
OK 232
3 seconds passed and you typed nothing!
$ ./a.out
32
OK 32
fewf
No enough arguments
$
It works as scanf but you pass the timeout first in seconds:
int sync_scanf(time_t sec, const char *format, ...);
It returns:
-1 on failure.
-2 on timeout.
Other than that it returns as scanf would does.
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>
int flag;
static sigjmp_buf jmpbuf;
static void sig_arm(int signo)
{
if(flag == -1)
return;
else if(flag == 0)
siglongjmp(jmpbuf,1);
}
int main(void){
int i, value;
signal(SIGALRM,sig_arm);
for (i=0;i<10;i++){
if(sigsetjmp(jmpbuf,0) == 0)
{
flag = 0;
alarm(5);
scanf(" %d", &value);
flag = 1;
}
if(flag == 0) // 5 second out
break;
}
flag = -1;
alarm(0);
}

Stop only if some key is pressed in C

If I had a while loop that I wanted to stop only if the q key is pressed how would I do that.
However, I do NOT want it to quite the program
#define TRUE 1
#define FALSE 0
typedef int boolean;
int main(int argc,char* argv[]){
char *script = malloc(MAXPATH);
script = "ls";
boolean a;
a = TRUE;
while(a){ //this is the while loop i want to break incase of a keypress
system(script);
}
do something else
something else....
This will be running on Mac OS X.
both getchar() and getc() pause for a response which makes loop stop
you can use select() mechanism in UNIX-LIKE OS.
all in one function:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
fd_set readfds;
struct timeval tv;
int ch;
int bool, ret;
FD_ZERO(&readfds);
bool = 1;
while (bool) {
FD_SET(STDIN_FILENO, &readfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
/* int select(int nfds, fd_set *readfds, fd_set *writefds,
* fd_set *exceptfds, struct timeval *timeout); */
ret = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv);
if (ret < 0) {
perror("select error");
exit(1);
} else if (ret == 0) {
/* timeout */
} else if (FD_ISSET(STDIN_FILENO, &readfds)) {
ch = fgetc(stdin);
if (ch == 'q') {
bool = 0;
}
}
sleep(1);
fprintf(stderr, ".");
}
return 0;
}
native functions in C with which i can detect a keypress are :
getchar() and getc()
kbhit() is a function returns integer value whenever the key is pressed
you can use the above functions
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <time.h>
int main()
{
int m;
clrscr();
do
{
if(kbhit())
{
if((m=getch())==97)
{
printf("Key a is pressed....\n");
}
}
} while(1);
getch();
return 0;
}
I'm glad of alexchandel's answer. I had never heard of poll()
poll() is a good answer for POSIX style systems like the questioner's platform
_kbhit() is the simplest answer on MS Windows. Their Poll() is different of course
The 1 means just one descriptor block in my list, the 100 is milliseconds timout
my file handle is { 0, for stdin
read the man page for the many events you can interrogate, I only wanted POLLIN
#include <stdio.h>
#include <poll.h>
#include <errno.h>
static struct pollfd attention = { 0, POLLIN } ;
int main()
{
int x, y;
for (;;)
{
x = poll(&attention, 1, 100);
if (x < 0)
{
printf("problem %d\n", errno);
break;
}
else if (x)
{
printf("you rang %x ?", x);
y = getc(stdin);
printf(" %c of course\n", y);
if (y == '.') break;
}
}
return 0;
}
You could make the computation run in a pthread while the main loop reads char on stdin. SDL library has better input controls if you don't just want to read char from stdin. gtk also has events that the window receives. The command "xev" is a xlib program for linux that works similarly. It opens a blank window and it reads key events as they come.

Resources