i am making a counting program, and i want to add a feature that quits the program, but i don’t really know how to do it. i have seen examples on how to do it, but all of them are for windows. please help
os is linux debian
i tried adding "i = getchar();" and then added an if: "if (i==1){break;}" but nothing happened. i was expecting it to get a value of 1 and then exit.
code:
#include <stdio.h>
//#include <threads.h>
#include <time.h>
#include <unistd.h>
int main() {
start:
struct timespec duration;
struct timespec remaining;
int time, num;
duration.tv_sec = 1;
duration.tv_nsec = 0;
time = 0;
num = 0;
while(time <= 32767)
{
int result = nanosleep(&duration, &remaining);
num++; //adds 1 to the number
if (result == 0)
{
printf("Seconds Passed: ");
printf("%dn", num); //prints the number
time++; //adds 1 to the time
}
else if (result == -1)
{
printf("Error with nanosleepn");
goto start;
}
}
getchar();
return 0;
}
2
Answers
You want to do two things at the same time:
There are generally two popular ways to implement multitasking:
Multithreading using standard C11 threads might look like the following:
While an event loop might look like this:
You might be interested in:
man pthread_create
man poll
man signal
man 7 signal
man sleep
man pipe
https://en.cppreference.com/w/c/thread .You might also be interested in How do you do non-blocking console I/O on Linux in C? to read
q
without having to press enter.The way you used
goto
in your code smells for me. Do not use goto (that way). You might be interested in https://en.wikipedia.org/wiki/Goto#Criticism . The kernel coding style https://www.kernel.org/doc/html/v4.18/process/coding-style.html#centralized-exiting-of-functions shows the only acceptable way to use goto. In the case of your presented code, you could have just used a normal loop.Here’s another approach.
This uses the underlying file descriptor for standard in and sets it to non-blocking. This prevents the read from waiting for input.
Note that this uses Unix-style calls, which are POSIX compliant, but not standard C library. Thus, this cannot easily be run as-is on Windows.
Also, this solution (as with KamilCuk’s solution) requires you to press return for your "q" to be read. If you want single-keystroke recognition, then you need to put the terminal driver into a special mode. I advise against doing that, partly due to the added complexity. Also, if your program exits prematurely without cleaning up, it will leave the terminal driver in the special mode, which you will not find usable. (There are things you can to do protect against even that, but it adds even more complexity.)
One more thing. KamilCuk’s solution reacts immediately to the keystroke. Mine waits till the loop gets to the
read()
. This might be an advantage or a disadvantage, depending on your needs.So three solutions. The right one depends on the details of your overall design. Mine is arguably the less complex, but also the least flexible, depending on what else is going on in your program.