如何让C程序在按下Q键时退出?

问题描述 投票:0回答:1

我正在制作一个计数程序,我想添加一个退出程序的功能,但我真的不知道该怎么做。我看过关于如何做到这一点的示例,但它们都是针对 Windows 的。请帮忙

操作系统是linux debian

我尝试添加“i = getchar();”然后添加了一个 if:“if (i==1){break;}”,但什么也没发生。我期望它的值为 1,然后退出。

代码:

#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("%d\n", num); //prints the number
          time++; //adds 1 to the time
      }
      else if (result == -1)
      {
         printf("Error with nanosleep\n");
         goto start;
      }
    }
    getchar();
    return 0;
}
c if-statement getchar
1个回答
0
投票

你想同时做两件事:

  • 运行一个带有睡眠打印秒数的循环
  • 等q

实现多任务处理通常有两种流行的方式:

  • 多线程/多处理
  • 事件循环

使用标准 C11 线程的多线程可能如下所示:

#include <signal.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stdio.h>
#include <threads.h>
#include <unistd.h>

int printer(void *arg) {
  // prints seconds until shoudlexit is set
  atomic_bool *shouldexit = arg;
  for (unsigned time = 0; time <= 32767; time++) {
    printf("Seconds Passed: %d\n", time);
    sleep(1);
    if (atomic_load(shouldexit)) {
      break;
    }
  }
  return 0;
}

void sigusr1_handler(int ignore) {}

int main() {
  atomic_bool shouldexit = ATOMIC_VAR_INIT(false);
  thrd_t thr;
  thrd_create(&thr, printer, &shouldexit);
  // wait for q or end of stream
  for (int c; (c = getchar()) != EOF;) {
    if (c == 'q') {
      break;
    }
  }
  printf("Exiting...\n");
  atomic_store(&shouldexit, true);
  // send yourself a signal to break sleep mid sleep.
  signal(SIGUSR1, sigusr1_handler);
  raise(SIGUSR1);
  thrd_join(thr, 0);
}

事件循环可能如下所示:

#include <poll.h>
#include <stdio.h>
#include <unistd.h>
int main() {
  struct pollfd fds[] = {{.fd = STDIN_FILENO, .events = POLLIN}};
  int time = 0;
  while (1) {
    int r = poll(fds, sizeof(fds) / sizeof(*fds), 1000);
    if (r == 0) {
      printf("Seconds Passed: %d\n", time);
      time++;
    } else {
      int c = getchar();
      if (c == EOF || c == 'q') {
        printf("Exiting...\n");
        break;
      }
    }
  }
}

您可能感兴趣:

man pthread_create
man poll
man signal
man 7 signal
man sleep
man pipe
https://en.cppreference.com/w/c/thread .

您可能还对 How do you do non-blocking console I/O on Linux in C in C? 感兴趣,无需按 Enter 键即可阅读

q

你在代码中使用

goto
的方式对我来说很臭。不要使用 goto (那样)。您可能对 https://en.wikipedia.org/wiki/Goto#Criticism 感兴趣。内核编码风格 https://www.kernel.org/doc/html/v4.18/process/coding-style.html#centralized-exiting-of-functions 显示了使用 goto 的唯一可接受的方式。对于您提供的代码,您可以只使用普通循环。

© www.soinside.com 2019 - 2024. All rights reserved.