通过从 C/C++ 替换 R 控制台中的输出来创建进度更新 [英] Creating a progress update by replacing output in the R console from C/C++
问题描述
是否可以使用 R 的 C/C++ 打印函数覆盖 R 控制台输出?
Is it possible to overwrite R console output with the C/C++ print functions for R?
Rcpp::sourceCpp( code = '
#include <Rcpp.h>
// [[Rcpp::export]]
void print_test() {
for(int i = 0; i < 10; i++) {
std::stringstream strs;
strs << "number: " << i;
std::string temp_str = strs.str();
char const* char_type = temp_str.c_str();
REprintf(char_type);
}
}'
)
print_test()
这个函数的输出是
number: 0number: 1number: 2number: 3number: 4number: 5number: 6number: 7number: 8number: 9
但我希望它是一个动态序列.例如:
but I want it to be a dynamic sequence. For example:
number: 0
等几秒钟:
number: 1
其中 number: 0
从控制台中完全删除.重复此过程,直到达到 number: 9
.
where number: 0
is completely erased from the console. This procedure repeats until number: 9
is reached.
我看过这个问题,但我没有能够让回车解决方案与 REprintf() 一起使用.
I've seen this question, but I was not able to get the carriage return solution to work with REprintf().
推荐答案
要正确更新 R 控制台,您需要使用 Rinterfaces.h
> 标题.此标头仅适用于类 Unix 系统.因此,您的进度更新将在 Windows 上中断.
To get the proper updates to the R console, you will need to use the Rinterfaces.h
header. This header is only available for unix-alike systems. Thus, your progress update will break on Windows.
特别是,您应该将 REprintf
(标准错误)或 Rprintf
(标准输出)与 R_FlushConsole
结合使用来更新控制台.这里的关键是用 "\r"
或回车符包围输出,这会强制返回到行的开头.这将导致您的值被打印,然后前一行被擦除".
In particular, you should use REprintf
(standard error) or Rprintf
(standard output) in combination with R_FlushConsole
to update the console. The key here is to surround output with "\r"
or a carriage return, which forces a return to the beginning of the line. This will cause your value to be printed and then the previous line to be "erased."
在此过程中,检查用户中断可能是有利的(例如,如果用户按下退出键,则退出进程).因此,我包含了对 R_CheckUserInterrupt()
的调用.
During this procedure, it may be advantageous to check for user interrupts (e.g. if user presses escape, exit the process). Thus, I've included a call to R_CheckUserInterrupt()
.
最后,为了强调正在发生更新,我选择了减慢循环,强制它每隔一秒左右休眠一次.
Lastly, to emphasize an update is happening, I've opted to slow the loop by forcing it to sleep every second or so.
#include <Rcpp.h>
// for unix-alike machines only
#if !defined(WIN32) && !defined(__WIN32) && !defined(__WIN32__)
#include <unistd.h>
#include <Rinterface.h>
#endif
// [[Rcpp::export]]
void print_test() {
int n = 10;
for(int i = 0; i < n; i++) {
#if !defined(WIN32) && !defined(__WIN32) && !defined(__WIN32__)
// Sleep for a second
usleep(1000000);
#endif
std::stringstream strs;
strs << "number: " << i;
std::string temp_str = strs.str();
char const* char_type = temp_str.c_str();
REprintf("\r");
REprintf("%s", char_type);
REprintf("\r");
#if !defined(WIN32) && !defined(__WIN32) && !defined(__WIN32__)
R_FlushConsole();
#endif
R_CheckUserInterrupt();
}
}
示例:
这篇关于通过从 C/C++ 替换 R 控制台中的输出来创建进度更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!