【问题标题】:Continue iterating/repeating while loop until enter (or arbitrary key) is pressed继续迭代/重复while循环,直到按下回车键(或任意键)
【发布时间】:2019-06-13 04:49:28
【问题描述】:

我试图让一个while循环进行迭代,直到按下一个键,理想情况下是输入。

具体来说,我想要一个值不断更新并对用户可见,直到他按下回车键。

这是我正在使用的基本代码,但它并没有像我希望的那样工作

while(1){       
    printf("Press Enter to Continue\n");    
    printf("Value to Update: %f\n",value_to_update); 
    usleep(10000);      
    system("clear"); 
    while(getchar() != '\n'){
        continue; 
    }       
}; 

谢谢。很高兴澄清我所说的任何内容或回答其他问题。

我不确定如何准确地解释我在寻找什么。我会尝试两种方法:

1) 我希望它执行以下代码的操作,除了在用户按下回车时停止:

while(1){           
    printf("Value to Update: %f\n",value_to_update); 
    usleep(10000);      
    system("clear"); 
};

2) 我会列举步骤

1) 将要更新的值打印到屏幕上

2) 等待N微秒

3) 用户按下是否输入?

3.False) 如果否:清屏,进入步骤1

3.True) 如果是:从循环中中断

我想这比我想象的要难得多。

【问题讨论】:

  • 您能否更具体地说明“无法按我的意愿工作”的意思?您看到的输出是什么?
  • 发布输入使用和输出看到,输出期望。
  • 如果你想让它在后台运行,而你在前台更新显示,你需要用户操作系统特定的代码,它不能在标准 C 中完成。
  • 旁注:我会将您的printf 呼叫移动到屏幕清晰之后。否则,它们将被输出,然后屏幕很快被清除,用户可能看不到它们,并且会留下一个空白屏幕,不知道该怎么做。
  • 听起来问题在于 getchar() “阻塞”。考虑使用curses。它是为文本模式“屏幕控制”定制的。就像等待用户点击 ... 或任何其他键,例如控制键。它可以从 C 中调用,并且与平台无关,包括 Windows 和 Linux。

标签: c while-loop user-input


【解决方案1】:
while(getchar() != '\n'){
        continue; 

它不会像你想的那样做。

你想打破第一个循环。

If(getchar() == char_which_breaks_the_loop) break;

【讨论】:

    【解决方案2】:

    这是使用select 调用的示例代码。

    适用于换行,因为内核 TTY 层将一直保持到 获得换行。

    因此,对于任何其他字符(例如空格),我们必须发出我在顶级 cmets 中提到的 ioctl 调用,以将图层置于“原始”模式(与默认的“熟”模式相比) .如果需要,请参阅 tcgetattrtcsetattr 调用。

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <time.h>
    #include <sys/time.h>
    #include <sys/select.h>
    
    int
    main(void)
    {
        int fd;
        char buf[10];
        int len;
        fd_set rdset;
    
        fd = 0;
    
        while (1) {
            // this is do whatever until newline is pressed ...
            printf(".");
            fflush(stdout);
    
            // set up the select mask -- the list of file descriptors we want to
            // wait on for read/input data available
            FD_ZERO(&rdset);
            FD_SET(fd,&rdset);
    
            // set timeout of 1ms
            struct timeval tv;
            tv.tv_sec = 0;
            tv.tv_usec = 1000;
    
            // wait for action on stdin [or loop if timeout]
            // the first arg must be: the highest fd number in the mask + 1
            len = select(fd + 1,&rdset,NULL,NULL,&tv);
            if (len <= 0)
                continue;
    
            // we're guaranteed at least one char of input here
            len = read(fd,buf,1);
            if (len <= 0)
                continue;
    
            // wait for newline -- stop program when we get it
            if (buf[0] == '\n')
                break;
        }
    
        printf("\n");
    
        return 0;
    }
    

    【讨论】:

    • 哇,谢谢。我真的很感激这一点。我不认为在一百万年后我会为自己弄清楚这一点。我知道这可能要求很多,但您介意评论您的代码吗?我想更好地了解这是在做什么。还是谢谢你。
    • 不客气。我不得不为生产代码摆弄这些东西,所以我已经有点熟悉了。
    • @GeneralPancake:在深入了解 ioctl()、select() 和朋友之前,请先考虑尝试ncurses
    猜你喜欢
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 2021-11-12
    • 2021-05-17
    • 2022-12-31
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    相关资源
    最近更新 更多