C编程,如何在等待用户输入时运行for循环

时间:2017-11-05 01:16:14

标签: c multithreading

对于我的编码任务,我遇到了麻烦。

我想要实现的目标是运行一个程序,每1分钟在'A'和'B'之间交替变量char OUTPUT。所以第一分钟,OUTPUT应该是A.第二分钟,它将是B.所以等等。

但是,如果用户输入字符P,则在返回A / B循环之前,OUTPUT将为P分钟。

我还没有完全放下代码,因为我的尝试都没有奏效。我尝试过使用while和for循环。但每次我使用scanf或getchar()时,程序都会无限期地停止等待用户输入。

void timer(){
int t, d, change;
char p;

for(t = 1; t <= 30000; t++)
for(d = 1; d <= 30000; d++){
    if(t == 30000){
        change = 1;
    }
    else if(p == 'p'){
        change = 0;
    }  
    else{
        p = getchar();
    }

是我现在所拥有的。这是一个相当不完整的函数,但是更改应该返回1或0,而在main函数中,如果它是1,则OUTPUT将变为A / B.

我也做了一些研究,大多数人都推荐多线程,但是我们还没有在课堂上学到这一点,所以我们不能将它用于程序。我也无法访问sleep()或delay()。基本上我只限于标准的c库。

2 个答案:

答案 0 :(得分:0)

要执行您需要的操作,即启用用户输入以更改定期输出,您需要:

  1. 关闭将执行定期输出的线程,并根据基于用户输入设置的主线程中的变量值更改它。
  2. 使用select执行异步输入读取,例如:https://stackoverflow.com/a/448982/4454124
  3. 既然你说你还没有覆盖线程,那可能不是你现在想要的方式,所以我建议选择路线,即使它不是标准C。

答案 1 :(得分:0)

如果您仍然卡住了,那么这是一个使用pselect的简短示例(设置为不阻止,例如struct timespec的两个字段都设置为0)。它只是使用无限循环来检查pselect以确定输入是否等待在stdin上读取。如果是这样,它会读取输入,如果用户输入P(或以P开头的任何字符串)P,则在恢复之前输出一次,每秒一次。 AB(无论在“&#39; P&#39;之前的最后一次显示)”。

我将当前时间段设置为10 sec.进行测试,只需调整#define PERIOD 10常量即可更改为您需要的秒数(例如60)我不是每个值A'sB'sP's ...

每分钟都要观看一分钟

使用pselect非常简单。它与select相同,除了timeval结构select用于时间而select没有sigmask参数。 (此处无关紧要)关键是将timespec结构的两个字段都设置为0,以便pselect不会阻止等待输入。你只需要调用它,如果返回是1,那么你有输入等待。然后它只是读取输入的问题(我选择了fgets因此它会读取并消耗尾随的&#39; \ n&#39;)。检查用户是否输入P(只需检查buf中的第一个字符),如果是,则开始输出P的新时段,否则只需继续与{{1}一起进行操作}或A输出。内联其他评论如下:

B

注意:这是一个特定的解决方案.Windows不提供#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <sys/select.h> #include <unistd.h> #define MAXC 64 /* size of buffer for fgets */ #define PERIOD 10 /* no. of seconds for alternating period */ /* simple function calling pselect, returns 1 when input waiting */ int haveinput (int filedes) { fd_set set; struct timespec timeout; /* Initialize the file descriptor set. */ FD_ZERO (&set); FD_SET (filedes, &set); /* Initialize the timeout data structure. */ timeout.tv_sec = 0; /* timeout 0 - immediately return, */ timeout.tv_nsec = 0; /* if NULL, blocks indefinitely. */ return pselect (filedes + 1, &set, NULL, NULL, &timeout, NULL); } int main (void) { int c = 'A', last = c; /* holds last 'A' or 'B' for pickup after 'P' */ unsigned long begin = time (NULL); /* begin seconds of period */ for (;;) { /* loop until 'q' entered or EOF */ unsigned long current = time (NULL); /* current seconds */ if (haveinput (STDIN_FILENO) == 1) { /* is input ready? */ char buf[MAXC] = ""; /* if so, get it! */ if (!fgets (buf, MAXC, stdin) || *buf == 'q') break; /* if EOF or 'q' -- bail */ if (*buf == 'P') { /* if user entered 'P' */ c = 'P'; /* set c = 'P' */ begin = time (NULL); /* restart time period */ } } else { putchar (c); /* if no imput read, output char */ fflush (stdout); /* output is buffered so fflush */ sleep (1); /* arbitrary second to wait */ } if (current - begin >= PERIOD) { /* end of period reached */ if (last == 'A') /* if last was 'A' use 'B' */ c = last = 'B'; else /* otherwise use 'A' */ c = last = 'A'; begin = time (NULL); /* restart time period */ putchar ('\n'); } } putchar ('\n'); return 0; } (MinGW也不提供)。而Windows提供的版本为sys/select.h通过select和lib Winsock2.h,它与此处的实现不一致。)

示例使用/输出

交替周期为10秒。而不是60:

Ws2_32.lib

尝试一下,仔细看看,如果你有其他问题,请告诉我。