如何在linux上通过从键盘获取任何值来打破C中的while循环?
我正在构建的程序在一个无限while循环中运行,其中包含一个开关盒。我想在每种情况下都插入一个while循环,并在循环中执行一些操作,但只要给出键盘输入,循环就会退出。这样,在从键盘获取输入后,另一个case将使用嵌套的while循环运行,并且该过程将继续 结构如下:如何在linux上通过从键盘获取任何值来打破C中的while循环?,c,linux,while-loop,C,Linux,While Loop,我正在构建的程序在一个无限while循环中运行,其中包含一个开关盒。我想在每种情况下都插入一个while循环,并在循环中执行一些操作,但只要给出键盘输入,循环就会退出。这样,在从键盘获取输入后,另一个case将使用嵌套的while循环运行,并且该过程将继续 结构如下: while()//infinite loop { ............... //operations ............... //operations switch
while()//infinite loop
{
............... //operations
............... //operations
switch()
{
case 1:
............... //operations
............... //operations
while()//infinite loop
{
..............
..............
exit if there is any input from keyboard
}
break;
case 2:
............... //operations
............... //operations
while()//infinite loop
{
..............
..............
exit if there is any input from keyboard
}
break;
case n:
............... //operations
............... //operations
while()//infinite loop
{
..............
..............
exit if there is any input from keyboard
}
break;
}
}
有什么方法可以做到这一点吗?Linux键盘输入是缓冲的,为了捕获一个在运行中被击中的键,您必须配置IO 在main()的顶部附近添加对的调用(请参见下面的代码) 在不等待回车(CR)的情况下,读取动态按下的键 代码: 注意:
term\u reset()
将在程序退出时自动调用(以重置终端参数)
您可以在程序中的任何位置调用now non-blockinggetchar()
,以检测按键
int i = getchar();
并检查是否按下了一个键:
if (i > 0) {
// key was pressed, code in `i`
}
例如,在您的程序中:
int key = 0;
while (... && key <= 0) {
// ...
key = getchar();
}
int键=0;
虽然(…&&key谢谢大家……尽管我的答案有点不合时宜,但我认为ring0的方法要好得多。
这就是我所做的
- 在外部while循环中添加了代码,允许编译器从文件(例如data.dat)中获取开关大小写的参数
- 如果从data.dat检索的变量是运行循环所需的变量,则在每个嵌套while循环中添加类似代码以继续,如果不是,则中断
- 因为在linux中我可以在后台运行进程,所以我在后台运行主程序,并相应地编辑data.dat
这个方法对我来说很有效,但肯定也会尝试ring0的方法。我也有同样的愿望,需要维护一个旧系统。我想添加一个“退出”并提供一些时间。我去掉了所有专有代码,留下了我从这个网站学到的内容。谢谢
我最后使用了上面的例子。我想发表评论,但我还没有达到那个水平
我还从by和
我不能使用fcntl,因为我们代码中使用的全局变量与fcntl中的某些内容冲突,我不想找出如何避免这种冲突
无论如何,这里有一个例子。它在Debian(旧版本)上对我有效。你的里程数可能会有所不同
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#define SLEEP 500000. /*usec*/
#include <termios.h>
struct termios stdin_orig;
void term_reset() {
tcsetattr(STDIN_FILENO, TCSANOW, &stdin_orig);
tcsetattr(STDIN_FILENO, TCSAFLUSH, &stdin_orig);
}
void term_nonblocking() {
struct termios term;
tcgetattr(STDIN_FILENO, &stdin_orig);
term = stdin_orig;
term.c_iflag |= IGNBRK;
//term.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF);
term.c_lflag &= ~(ICANON);// | ECHO | ECHOK | ECHOE | ECHONL | ISIG | IEXTEN);*/
term.c_cc[VMIN] = 0;
term.c_cc[VTIME] = 0;
/* fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); // non-blocking */
tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
// end mikes timing
int main (void)
{
int key=0;
// mikes test variables
long mnloops = 0;
double mttot = 0.0;//total time elapsed in difference between start-end.
term_nonblocking();
// end mikes test variables
/*main loop*/
do{
//mikes timing
puts("Start Do");
time_t mnow;
struct timeval mtv;
struct timezone mtz;
time(&mnow);
gettimeofday(&mtv, &mtz);
double startTime = (double)mnow + mtv.tv_usec/1e6;
// end mikes timing
usleep(SLEEP);
puts("got hey");
//mikes timing
time(&mnow);
gettimeofday(&mtv, &mtz);
mttot += (((double)mnow + mtv.tv_usec/1e6) - startTime);
mnloops++;
key = getchar();
// end mikes timing
}while (1 && key != 'q');/* end of main loop*/
term_reset();
printf("DONE: average time per loop = %-10.4e\n",mttot/mnloops);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#定义睡眠时间。/*usec*/
#包括
结构术语标准格式;
无效项_重置(){
tSetAttr(标准文件号、标准名称和标准原件);
tcsetattr(标准文件号、TCSAFLUSH和标准原始文件);
}
无效项_非阻塞(){
结构术语;
tcgetattr(标准文件号和标准原件);
术语=stdin_orig;
术语c|u iflag |=IGNBRK;
//术语c|u iflag&=~(INLCR | ICRNL | IXON | IXOFF);
term.c|lflag&=~(ICANON);/| ECHO | ECHOK | ECHO | ECHONL | ISIG | IEXTEN)*/
术语c_cc[VMIN]=0;
term.c_cc[VTIME]=0;
/*fcntl(标准文件号、设置符、非块);//非块*/
tcsetattr(标准文件号、TCSANOW和术语);
}
//末端麦克风定时
内部主(空)
{
int键=0;
//mikes测试变量
长mnloops=0;
double mttot=0.0;//以开始和结束之间的差值表示的总时间。
术语_非阻塞();
//端mikes测试变量
/*主回路*/
做{
//麦克风定时
看跌期权(“开始做”);
时间;
结构时间值mtv;
结构时区mtz;
时间(&mnow);
gettimeofday(&mtv,&mtz);
双开始时间=(双)mnow+mtv.tv\u usec/1e6;
//末端麦克风定时
usleep(睡眠);
放置(“得到嘿”);
//麦克风定时
时间(&mnow);
gettimeofday(&mtv,&mtz);
mttot+=((双)mnow+mtv.tv_usec/1e6)-开始时间);
mnloops++;
key=getchar();
//末端麦克风定时
}while(1&&key!='q');/*主循环结束*/
术语_reset();
printf(“完成:每个循环的平均时间=%-10.4e\n”,mttot/mnloops);
返回0;
}
您是在询问如何获得键盘输入,还是如何打破嵌套循环?您是在询问如何进行原始输入,以便在按下任何产生字符或控制代码的键时,等待就结束了,而不是被迫按enter键(在可选地输入一些文本后)?无论键盘问题的解决方案如何,这个函数应该被重构。我需要知道如何用键盘输入来中断嵌套循环,这样,当外部while循环运行时,输入会再次被输入到外壳中。我计划做的是,当按下一个键,嵌套的while循环中断时,该键被写入一个文件。然后,当外部while循环再次运行时,此键将作为文件的输入,用于切换。实际上,可以在切换后进行等待,在所有情况下都是一次,而不是重复代码。如果您读取字符以便外部循环可以再次处理它,您可能需要ungetc(i,stdin)
。@JonathanLeffler谢谢。这确实是很有价值的信息。请注意,如果没有按下某个键,getchar()将返回-1或0。我使用了(key@stacey谢谢),编辑了答案,因为它可能会帮助其他人。
int key = 0;
while (... && key <= 0) {
// ...
key = getchar();
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#define SLEEP 500000. /*usec*/
#include <termios.h>
struct termios stdin_orig;
void term_reset() {
tcsetattr(STDIN_FILENO, TCSANOW, &stdin_orig);
tcsetattr(STDIN_FILENO, TCSAFLUSH, &stdin_orig);
}
void term_nonblocking() {
struct termios term;
tcgetattr(STDIN_FILENO, &stdin_orig);
term = stdin_orig;
term.c_iflag |= IGNBRK;
//term.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF);
term.c_lflag &= ~(ICANON);// | ECHO | ECHOK | ECHOE | ECHONL | ISIG | IEXTEN);*/
term.c_cc[VMIN] = 0;
term.c_cc[VTIME] = 0;
/* fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); // non-blocking */
tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
// end mikes timing
int main (void)
{
int key=0;
// mikes test variables
long mnloops = 0;
double mttot = 0.0;//total time elapsed in difference between start-end.
term_nonblocking();
// end mikes test variables
/*main loop*/
do{
//mikes timing
puts("Start Do");
time_t mnow;
struct timeval mtv;
struct timezone mtz;
time(&mnow);
gettimeofday(&mtv, &mtz);
double startTime = (double)mnow + mtv.tv_usec/1e6;
// end mikes timing
usleep(SLEEP);
puts("got hey");
//mikes timing
time(&mnow);
gettimeofday(&mtv, &mtz);
mttot += (((double)mnow + mtv.tv_usec/1e6) - startTime);
mnloops++;
key = getchar();
// end mikes timing
}while (1 && key != 'q');/* end of main loop*/
term_reset();
printf("DONE: average time per loop = %-10.4e\n",mttot/mnloops);
return 0;
}