gpt4 book ai didi

c - 如何使 C 程序停止任何用户输入的循环?

转载 作者:太空狗 更新时间:2023-10-29 15:33:15 25 4
gpt4 key购买 nike

我想编写一个运行无限循环的小 C 程序,直到用户按下键盘上的一个键(即:stdin 缓冲区中有一个字符)。我在打破用户输入循环时遇到了麻烦。我试过使用 fgetc 但它的行为不如预期。下面的代码等待用户输入而不是运行直到用户输入。

示例 C 代码:

while((c=fgetc(stdin) == EOF) {
/* Does stuff for infinite loop here */
printf("Example work in the loop\n");
}
printf("Out of the loop!\n");

如何编写一个在用户干预之前一直执行的循环?按任意键或特定键可能是干预触发器。

注意 1:我正在为特定于平台的解决方案的 Unix 控制台编写此代码

注意2:不建议将Ctrl + C/X/Z作为用户干预触发器

最佳答案

这似乎对我有用:

#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

static void set_non_blocking(int fd)
{
int flags = fcntl(fd, F_GETFL, 0 );
flags |= O_NONBLOCK;
flags = fcntl(fd, F_SETFL, flags);
}


int main(int argc, char ** argv)
{
int fd = fileno(stdin);
char buf[10];

set_non_blocking(fd);

while (read(fd, buf, sizeof buf) < 0) {
perror("read");
sleep(1);
}
return 0;
}

或者你可以使用select:

int main(int argc, char ** argv)
{
int fd = fileno(stdin);
struct timeval tv = {0,0};
fd_set fdset;
int s;

do {
sleep(1);
FD_ZERO(&fdset);
FD_SET(fd, &fdset);

} while ((s = select(fd+1, &fdset, NULL, NULL, &tv)) == 0);

if (s < 0) {
perror("select");
}
return 0;
}

投票也有效:-)

int main(int argc, char ** argv)
{
struct pollfd pfd;
int s;

pfd.fd = fileno(stdin);
pfd.events = POLLRDNORM;

while ((s = poll(&pfd, 1, 0)) == 0) {
perror("polling");
sleep(1);
}
if (s < 0) {
perror("poll");
}
return 0;
}

最后一种方法是将终端设置为“原始”模式。请注意,这会扰乱终端的输出(至少在我的 OS-X 上),因为在\n 之后\r 变得必要。另请注意,它需要在最后撤消(终止 tcsetattr 调用)。这是唯一不需要\n 的(即任何按键都可以)

#include <poll.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>


static void set_non_blocking(int fd)
{
int flags = fcntl(fd, F_GETFL, 0) | O_NONBLOCK;

if (fcntl(fd, F_SETFL, flags) < 0) {
perror("fcntl");
exit(EXIT_FAILURE);
}
}


int main(int argc, char ** argv)
{
struct termios params;
struct termios params_orig;
char buf[10];
int fd = fileno(stdin);

if (tcgetattr(fd, &params) < 0) {
perror("tcgetattr");
exit(EXIT_FAILURE);
}
params_orig = params;

cfmakeraw(&params);

if (tcsetattr(fd, TCSANOW, &params) < 0) {
perror("tcsetattr");
exit(EXIT_FAILURE);
}
set_non_blocking(fd);

while (read(fd, buf, sizeof buf) < 0) {
perror("\rread");
sleep(1);
}

(void) tcsetattr(fd, TCSANOW, &params_orig);
return 0;
}

关于c - 如何使 C 程序停止任何用户输入的循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13426575/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com