Я хочу написать программу для выполнения команды R с использованием RInside и сказать, является ли результат строкой. Я создал экземпляр RInside и использовал его метод RInside :: parseEval для анализа команды R, а затем сохранил результат в переменной SEXP. Я использовал TYPEOF , чтобы проверить, является ли тип результата строкой, и затем преобразовал его в R cpp :: 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");
}
}
Когда я запустил программу с агрументом "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 указывает на (ноль)
Результат не является строкой
Так что мой вопрос, почему так себя вести? Когда кто-то анализирует команду ошибки с RInside::parseEval
, будет ли сгенерировано исключение, или результатом будет нулевой указатель, или произойдет хотя бы один из этих случаев? Правильно ли работает мой код выше?
Любая помощь будет благодарна.
Edit 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
}
Результат приведенного выше кода равен
Результат привет