C++ 通过从C/C+替换R控制台中的输出来创建进度更新+;
是否可以用R的C/C++打印函数覆盖R控制台输出C++ 通过从C/C+替换R控制台中的输出来创建进度更新+;,c++,r,rcpp,C++,R,Rcpp,是否可以用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
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: 0
请稍等几秒钟:
number: 1
其中number:0
从控制台中完全删除。重复此过程,直到达到编号9为止
我已经看到了这个问题,但我无法使回车解决方案与REprintf()配合使用。要获得对R控制台的正确更新,需要使用标题。此标头仅适用于类似unix的系统。因此,您的进度更新将在Windows上中断 特别是,您应该将
REprintf
(标准错误)或Rprintf
(标准输出)与R\u FlushConsole
结合使用来更新控制台。这里的关键是用“\r”
或回车符环绕输出,这将强制返回到行的开头。这将导致打印您的值,然后“擦除”上一行
在此过程中,检查用户中断可能是有利的(例如,如果用户按下escape,则退出该过程)。因此,我包含了对R\u 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();
}
}
#包括
//仅适用于类似unix的计算机
#如果!已定义(WIN32)&!已定义(uu WIN32)&&!已定义(uuu WIN32_uuu)
#包括
#包括
#恩迪夫
//[[Rcpp::导出]]
无效打印测试(){
int n=10;
对于(int i=0;i strs你有反向。当从R调用时,我们只允许使用R的输出工具。CRAN包永远不允许覆盖R的内部输出。我觉得这可能在Rinterfaces.h
(R\u FlushConsole()
)中丢失了一些东西,类似于进度条更新。所以,可能是的,“输入”字符串很好,“覆盖”“正如你的标题所暗示的那样,情况并非如此。@DirkEddelbuettel感谢你的澄清。@Coatbless感谢你改进了我的问题。有趣的是,你提到RcppProgress,因为我正是为了这个问题而问的。太好了!这完全符合预期。但是:据我所知,你确定没有平台独立的解决方案吗。
#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();
}
}