使用键盘输入中断循环 (R)

Ala*_*lan 5 r while-loop rstudio

我需要一个 R 循环来继续运行,直到用户按下某个键。像下面这样的东西。有任何想法吗?我是 R 新手

while(FALSE_after_user_input){
  queryWebApi()
  Sys.sleep(1)
}
Run Code Online (Sandbox Code Playgroud)

编辑 1

我真正想要的是一种停止数据收集的方法。我有一个函数,我想每隔几秒运行一次来​​查询新数据。用户需要能够停止数据收集循环。

readline() 不起作用,因为它停止执行数据收集循环

Wei*_*ong 4

建议一: TCL/TK

library(tcltk)
win1 <- tktoplevel()
butStop <- tkbutton(win1, text = "Stop",
  command = function() {
    assign("stoploop", TRUE, envir=.GlobalEnv)
    tkdestroy(win1)
})
tkgrid(butStop)

stoploop <- FALSE
while(!stoploop) {
    cat(". ")
    Sys.sleep(1)
}
cat("\n")
Run Code Online (Sandbox Code Playgroud)

一些代码借用:触发函数调用的按钮

建议2:对标准输入进行非阻塞检查。(请注意:C这不是我的核心能力,我从互联网上拼凑而成。)主要思想是编写一个C等待用户输入的函数,并从R.

下面的片段改编自循环中的非阻塞用户输入。将以下代码另存为kbhit.c

#include <stdio.h>
#include <unistd.h>
#include <R.h>

void kbhit(int *result)
{
    struct timeval tv;
    fd_set fds;
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    FD_ZERO(&fds);
    FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
    *result = FD_ISSET(STDIN_FILENO, &fds);
}
Run Code Online (Sandbox Code Playgroud)

然后,从命令行运行R CMD SHLIB kbhit.c以将其编译为R.

最后,在 中R,加载新创建的kbhit.so,编写一个返回函数kbhit输出的函数 ( ) C,然后运行循环。 kbhit()除非收到回车键,否则返回 0。请注意,停止循环的唯一方法是按 Enter/Return(或硬中断)——如果您想要更灵活的方法,请参阅上面的链接。

dyn.load("kbhit.so")

kbhit <- function() {
    ch <- .C("kbhit", result=as.integer(0))
    return(ch$result)
}

cat("Hit <enter> to stop\n")
while(kbhit()==0) {
    cat(". ")
    Sys.sleep(1)
}
Run Code Online (Sandbox Code Playgroud)

.C有关接口的更多详细信息R

在 Windows 机器上:

kbhit.c

#include <stdio.h>
#include <conio.h>
#include <R.h>

void do_kbhit(int *result) {
    *result = kbhit();
}
Run Code Online (Sandbox Code Playgroud)

R

dyn.load("kbhit.dll")

kbhit <- function() {
    ch <- .C("do_kbhit", result=as.integer(0))
    return(ch$result)
}

cat("Hit any key to stop\n")
while(kbhit()==0) {
    cat(". ")
    Sys.sleep(1)
}
Run Code Online (Sandbox Code Playgroud)

PS我通过谷歌搜索将其组合在一起,所以不幸的是我不知道它是如何或为什么工作的(如果它对你有用的话!)。