通过从 C/C++ 替换 R 控制台中的输出来创建进度更新
Creating a progress update by replacing output in the R console from C/C++
是否可以使用 R 的 C/C++ 打印函数覆盖 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
但我希望它是一个动态序列。例如:
number: 0
稍等几秒:
number: 1
其中 number: 0
已从控制台中完全删除。重复此过程,直到达到 number: 9
。
我已经看到 this 问题,但我无法获得与 REprintf() 一起使用的回车 return 解决方案。
要正确更新 R 控制台,您需要使用 Rinterfaces.h
header。此 header 仅适用于 unix-alike 系统。因此,您的进度更新将在 Windows.
中断
特别是,您应该结合使用 REprintf
(标准错误)或 Rprintf
(标准输出)和 R_FlushConsole
来更新控制台。这里的关键是用 "\r"
或回车符 return 包围输出,这会强制 return 到行的开头。这将导致打印您的值,然后上一行为 "erased."
在此过程中,检查用户中断可能是有利的(例如,如果用户按退出键,退出进程)。因此,我包含了对 R_CheckUserInterrupt()
的调用。
最后,为了强调正在进行更新,我选择了 减慢 循环,迫使它每隔一秒左右进入休眠状态。
#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();
}
}
示例:
是否可以使用 R 的 C/C++ 打印函数覆盖 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
但我希望它是一个动态序列。例如:
number: 0
稍等几秒:
number: 1
其中 number: 0
已从控制台中完全删除。重复此过程,直到达到 number: 9
。
我已经看到 this 问题,但我无法获得与 REprintf() 一起使用的回车 return 解决方案。
要正确更新 R 控制台,您需要使用 Rinterfaces.h
header。此 header 仅适用于 unix-alike 系统。因此,您的进度更新将在 Windows.
特别是,您应该结合使用 REprintf
(标准错误)或 Rprintf
(标准输出)和 R_FlushConsole
来更新控制台。这里的关键是用 "\r"
或回车符 return 包围输出,这会强制 return 到行的开头。这将导致打印您的值,然后上一行为 "erased."
在此过程中,检查用户中断可能是有利的(例如,如果用户按退出键,退出进程)。因此,我包含了对 R_CheckUserInterrupt()
的调用。
最后,为了强调正在进行更新,我选择了 减慢 循环,迫使它每隔一秒左右进入休眠状态。
#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();
}
}
示例: