Rit*_*ika 13 c windows user-input
我正在尝试编写一个程序,其中一个数字从0开始,但当你按任意键时,它会增加1.如果没有按任何一个,它会继续每秒减少1,直到它达到0.每个增量或递减显示在控制台窗口中.
我的方法的问题是,在我按下一个键之前没有任何反应(也就是说,它检查是否有任何按下getch()).如何检查没有按下任何内容?当然,!getch()不起作用,因为要工作,它仍然需要检查按键,这会使目的本身无效.
操作系统:Windows 10企业版,IDE:代码::块
void main()
{
int i, counter = 0;
for (i = 0; i < 1000; i++)
{
delay(1000);
// if a key is pressed, increment it
if (getch())
{
counter += 1;
printf("\n%d", counter);
}
while (counter >= 1)
{
if (getch())
{
break;
}
else
{
delay(1000);
counter--;
printf("\n%d", counter);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*ins 11
以下简短程序既不需要ncurses也不需要线程.但是,它确实需要更改终端属性 - 使用tcsetattr().这适用于Linux和类Unix系统,但不适用于Windows - 不包括termios.h头文件.(如果您对该主题感兴趣,也许可以看这篇文章.)
#include <stdio.h>
#include <string.h>
#include <termios.h>
int main(int argc, char *argv[]) {
struct termios orig_attr, new_attr;
int c = '\0';
// or int n = atoi(argv[1]);
int n = 5;
tcgetattr(fileno(stdin), &orig_attr);
memcpy(&new_attr, &orig_attr, sizeof(new_attr));
new_attr.c_lflag &= ~(ICANON | ECHO);
new_attr.c_cc[VMIN] = 0;
// Wait up to 10 deciseconds (i.e. 1 second)
new_attr.c_cc[VTIME] = 10;
tcsetattr(fileno(stdin), TCSANOW, &new_attr);
printf("Starting with n = %d\n", n);
do {
c = getchar();
if (c != EOF) {
n++;
printf("Key pressed!\n");
printf("n++ => %d\n", n);
} else {
n--;
printf("n-- => %d\n", n);
if (n == 0) {
printf("Exiting ...\n");
break;
}
if (feof(stdin)) {
//puts("\t(clearing terminal error)");
clearerr(stdin);
}
}
} while (c != 'q');
tcsetattr(fileno(stdin), TCSANOW, &orig_attr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
关键点是
new_attr.c_lflag &= ~(ICANON | ECHO);
Run Code Online (Sandbox Code Playgroud)
使终端退出规范模式(并禁用字符'echo'),
new_attr.c_cc[VMIN] = 0;
Run Code Online (Sandbox Code Playgroud)
将它置于轮询(而不是"阻塞")模式,和
new_attr.c_cc[VTIME] = 10;
Run Code Online (Sandbox Code Playgroud)
指示程序等待直到输入10个十分.
更新(2019-01-13)
clearerr(stdin)清除(在某些平台EOF上stdin似乎是必要的)这是一个在 Linux 上运行的 pthread 示例。这个概念是好的,但是可能有现有的循环/库。
#include <stdio.h>
#include<pthread.h>
void *timer(void* arg){
int* counter = (int*)arg;
while(*counter > 0){
int a = *counter;
printf("counter: %d \n", a);
*counter = a - 1;
sleep(1);
}
}
int main(int arg_c, char** args){
int i = 100;
pthread_t loop;
pthread_create(&loop, NULL, timer, &i);
while(i>0){
i++;
getchar();
printf("inc counter: %d \n", i);
}
printf("%d after\n", i);
pthread_join(loop, NULL);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这将启动第二个线程,其中有倒计时。这会每秒减少计数器一次。在主线程上它有一个带有 getchar 的循环。他们都修改i.