中断C语言中的程序流
我已经运行了一个循环,每次迭代都会增加一个变量的值,我希望能够点击键盘上的一个键来停止循环并报告变量的最终值。问题是,我不知道如何在C语言中实现这一点。我觉得自己很愚蠢,因为我似乎忽略了一些简单易行的方法,但我尝试的每件事都会停止循环,直到我按下键盘上的一个键,这基本上与我想要的恰恰相反 基本上我想做的是这样的:中断C语言中的程序流,c,keyboard,program-flow,C,Keyboard,Program Flow,我已经运行了一个循环,每次迭代都会增加一个变量的值,我希望能够点击键盘上的一个键来停止循环并报告变量的最终值。问题是,我不知道如何在C语言中实现这一点。我觉得自己很愚蠢,因为我似乎忽略了一些简单易行的方法,但我尝试的每件事都会停止循环,直到我按下键盘上的一个键,这基本上与我想要的恰恰相反 基本上我想做的是这样的: 当(按键未按下时) 增量值 打印最终值 这有意义吗?无论如何,关于如何在C中实现这一点的任何提示都取决于您的平台。C语言没有定义这样的东西 窗户?linux?(gnome应用程序?
当(按键未按下时)
增量值
打印最终值
这有意义吗?无论如何,关于如何在C中实现这一点的任何提示都取决于您的平台。C语言没有定义这样的东西
窗户?linux?(gnome应用程序?kde应用程序?终端?)还有什么吗?这取决于您的平台。C语言没有定义这样的东西
窗户?linux?(gnome应用程序?kde应用程序?终端?)还有什么吗?您正在调用以读取字符的函数正在阻塞。如果没有字符,您希望它返回
这里的神奇搜索词是非阻塞和非/非阻塞输入。您正在调用的读取字符的函数是阻塞。如果没有字符,您希望它返回
这里的神奇搜索词是非阻塞和非/非缓冲输入。为什么循环计数直到有人按下键才有意义 如果你真的想要这样的东西,你可以检查一下10公里的时间安排。
然后在非阻塞状态下等待睡眠()。当你得到时间时,你可以用它来近似“最终值”是多少为什么循环计数直到有人按下键才有意义 如果你真的想要这样的东西,你可以检查一下10公里的时间安排。
然后在非阻塞状态下等待睡眠()。当您获得时间时,您可以使用它来近似“最终值”是多少如果您试图一次从linux中的终端读取一个字符(不按enter键),则需要将终端设置为非缓冲输入 请参见此示例:
如果您试图在linux中从终端一次读取一个字符(不按enter键),则需要将终端设置为非缓冲输入 请参见此示例:
如果您在windows上工作,并且正在使用MSVC,那么您可能需要getch()和kbhit(),类似的东西
#include <conio.h>
while( looping ) {
// do regular loop stuff
// check if a key is hit, w/o blocking, using kbhit()
if( kbhit() ) {
// only runs when user has hit a key
// so display stuff here,
// and wait for permission to resume with getch()
getch();
}
}
#包括
while(循环){
//做常规的循环
//使用kbhit()检查键是否被击中,不带阻塞
if(kbhit()){
//仅在用户按下键时运行
//所以在这里展示东西,
//并等待使用getch()恢复的权限
getch();
}
}
如果您使用的是windows,并且使用的是MSVC,那么您可能需要getch()和kbhit(),类似的东西
#include <conio.h>
while( looping ) {
// do regular loop stuff
// check if a key is hit, w/o blocking, using kbhit()
if( kbhit() ) {
// only runs when user has hit a key
// so display stuff here,
// and wait for permission to resume with getch()
getch();
}
}
#包括
while(循环){
//做常规的循环
//使用kbhit()检查键是否被击中,不带阻塞
if(kbhit()){
//仅在用户按下键时运行
//所以在这里展示东西,
//并等待使用getch()恢复的权限
getch();
}
}
如果允许您指定按下的内容,并且您使用的是兼容POSIX.1的系统,则可以设置信号处理程序来捕获SIGINT(通过Ctrl+C发送)。让处理程序更改变量的值,使您脱离while循环
如果你选择这种方法,要小心。如果不正确的实现导致无限循环和捕获的SIGINT,您将无法通过Ctrl+C终止程序。在这种情况下,您需要使用kill(1)来终止程序。如果允许您指定按下的内容,并且您在符合POSIX.1的系统上,您可以设置一个信号处理程序来捕获SIGINT(由Ctrl+C发送)。让处理程序更改变量的值,使您脱离while循环
如果你选择这种方法,要小心。如果不正确的实现导致无限循环和捕获的SIGINT,您将无法通过Ctrl+C终止程序。在这种情况下,您需要使用kill(1)来终止程序。这是C标准让程序员无所事事的地方。这个问题的最可移植的解决方案是使用库进行I/O操作,该库处理所谓的“原始”键盘输入(这是您想要的)以及更多。学习曲线有点陡峭,但是有很好的教程,特别是在BSD程序员文档中。这是C标准让程序员们绞尽脑汁的地方。这个问题的最可移植的解决方案是使用库进行I/O操作,该库处理所谓的“原始”键盘输入(这是您想要的)以及更多。学习曲线有点陡峭,但有很好的教程,特别是在BSD程序员的文档中。根据系统及其工作方式,您可以尝试将选择函数与STDIN一起用作文件句柄。您可以将select语句上的时间设置为零,以轮询是否有数据,或者将其设置为等待时间 您可以查看链接,以获取将select语句与套接字一起使用的示例 我修改了这个示例,使用STDIN作为文件描述符。如果没有挂起的输入,函数将返回0;如果有挂起的输入(即有人按了输入键盘上的键),函数将返回1;如果有某种性质的错误,函数将返回-1
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
int waitForKBInput(unsigned int seconds)
{
/* File descriptor set on which to wait */
fd_set set;
/* time structure which indicate the amount of time to
wait. 0 will perform a poll */
struct timeval timeout;
/* Initialize the file descriptor set. */
FD_ZERO (&set);
/* Use the Standard Input as the descriptor on which
to wait */
FD_SET (STDIN, &set);
/* Initialize the timeout data structure. */
timeout.tv_sec = seconds;
timeout.tv_usec = 0;
/* select returns 0 if timeout, 1 if input available, -1 if error. */
/* and is only waiting on the input selection */
return select (FD_SETSIZE,
&set, NULL, NULL,
&timeout));
}
#包括
#包括
#包括
#包括
#包括
整数waitForKBInput(无符号整数秒)
{
/*要等待的文件描述符集*/
fd_集;
/*时间结构,它指示需要的时间量
等等,0将被删除
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
long globalvar = 0;
int interrupts_before_exit = 3;
void ctrl_c_handler(int x) {
printf("Value of the variable: %ld\n", globalvar);
if(--interrupts_before_exit) {
printf("Press Ctrl-C %d more times to stop\n", interrupts_before_exit);
} else {
printf("Computation interrupted!\n");
exit(0);
}
}
int main(int argc, char *argv[]) {
struct sigaction act;
act.sa_handler = ctrl_c_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if(sigaction(SIGINT, &act, NULL) >= 0) {
while (1) {
/* The work happens here */
globalvar++;
}
}
exit(1);
}
/* testbrk
Test breaking an infinite loop with a keystroke.
Hit the <Enter> key to break this loop.
*/
/* Include block */
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/*---testbrk main loop---*/
int main ( int argc , char ** argv )
{
/* Variables: file flags , return value , buffer */
int f ;
ssize_t r ;
char b ;
/*
Switch standard input to non-blocking mode:
-Get existing flags from the file descriptor
-Bitwise OR to activate non-blocking bit
-Apply new flags
*/
if ( f = fcntl( STDIN_FILENO , F_GETFL , 0 ) == -1 )
{
perror ( "fcntl F_GETFL" ) ;
exit ( EXIT_FAILURE ) ;
}
f |= O_NONBLOCK ;
if ( f = fcntl( STDIN_FILENO , F_SETFL , f ) == -1 )
{
perror ( "fcntl F_SETFL" ) ;
exit ( EXIT_FAILURE ) ;
}
/*
Infinite loop
-try reading from standard input directly via its file
descriptor , NOT the standard input stream
-if the number of bytes returned is > zero then break
-if bytes returned is -1 then check errno for EAGAIN,
meaning that read would block but the file is nonblocking
-if zero is returned then print message immediately
*/
while ( (r = read( STDIN_FILENO , &b , sizeof( b ) )) < 1 )
{
if ( r == -1 && errno != EAGAIN )
{
perror ( "read" ) ;
exit ( EXIT_FAILURE ) ;
}
fprintf ( stderr , "\nInfinite loop" ) ;
} /* inf loop */
/* Done */
printf ( "\n\nBroken loop\n\n" ) ;
exit ( EXIT_SUCCESS ) ;
} /* testbrk */