4

我想编写一个程序来使用 RInside 执行 R 命令并判断结果是否为字符串。我创建了一个 RInside 实例并使用它的方法RInside::parseEval来解析 R 命令,然后将结果存储在 SEXP 变量中。我使用TYPEOF检查结果的类型是否为字符串,然后使用其构造函数将其转换为Rcpp::String。问题是,当我尝试解析诸如之类的错误命令时,程序的行为变得有些不可预测。程序如下图所示:paste('hello

#include <RInside.h>
#include <stdio.h>

int main(int argc, char* argv[])
{

        RInside *R = new RInside();
        const char *expr = argv[1];

        SEXP res = NULL;
        try{
                res = R->parseEval(expr);
        } catch (std::exception &e) {
                res = NULL;
                printf("Exception thrown\n");
        }

        printf("res points to %p\n", res);
        if (res != NULL && TYPEOF(res) == STRSXP) {
                Rcpp::String res_str = res;
                printf("The result is a string: %s\n", res_str.get_cstring());
        } else {
                printf("The result is not a string");
        }
}

当我用 agrument 运行程序时"paste('hello'",我得到了输出

res 指向 0x7f0ca84e14d0

结果不是字符串

但是,当我将代码打包成一个函数时,如图所示:

#include <RInside.h>
#include <stdio.h>

void test_R(RInside *R, const char *expr)
{
        SEXP res = NULL;
        try{
                res = R->parseEval(expr);
        } catch (std::exception &e) {
                res = NULL;
                printf("Exception thrown\n");
        }

        printf("res points to %p\n", res);
        if (res != NULL && TYPEOF(res) == STRSXP) {
                Rcpp::String res_str = res;
                printf("The result is a string: %s\n", res_str.get_cstring());
        } else {
                printf("The result is not a string");
        }
}

int main(int argc, char* argv[])
{

        RInside *R = new RInside();
        const char *expr = argv[1];
        
        test_R(R, expr);
}

并使用与以前相同的命令行参数运行它"paste('hello'",我得到了输出

res 指向 (nil)

结果不是字符串

所以我的问题是,为什么它会这样?当使用 解析错误命令时RInside::parseEval,是否会引发异常或结果是否为 NULL 指针,或者至少会发生其中一种情况?我上面的代码是否正确地完成了它的工作?

任何帮助将不胜感激。

编辑0:

在花了一些时间阅读代码之后,R 似乎将该命令paste('hello视为“不完整”,这意味着如果我们稍后发送另一个命令来“完成”它,它将成功执行。

#include <RInside.h>
#include <stdio.h>

void test_R(RInside *R, const char *expr, int is_ok)
{
        SEXP res = R->parseEval(expr);
        if (is_ok) {
                std::string res_str = Rcpp::String(res);
                printf("The result is %s\n", res_str.c_str());
        }
}

int main()
{

        RInside R;
        const char *head = "paste('hello";
        const char *tail = "')";

        test_R(&R, head, 0); // This will parse "paste('hello"
        test_R(&R, tail, 1); // This will parse the rest of the command
}

上面代码的结果是

结果你好

4

0 回答 0