2013-02-19 44 views
6

Tôi đang cố truyền một vectơ ký tự từ R đến C và tham khảo nó thông qua một con trỏ ký tự C. Tuy nhiên, tôi không biết macro chuyển đổi loại nào sẽ sử dụng. Dưới đây là một thử nghiệm nhỏ minh họa vấn đề của tôi.Làm cách nào để chuyển đổi một vector ký tự R thành con trỏ ký tự C?

test.c File:

#include <Rinternals.h> 

SEXP test(SEXP chars) 
{ 
    char *s; 

    s = CHAR(chars); 
    return R_NilValue; 
} 

file test.R:

dyn.load("test.so") 

chars <- c("A", "B") 

.Call("test", chars) 

Output từ R:

> source("test.R") 
Error in eval(expr, envir, enclos) : 
    CHAR() can only be applied to a 'CHARSXP', not a 'character' 

Bất kỳ manh mối?

Trả lời

4

Chuỗi trong chars có thể được lấy bằng cách từng nhân vật thông qua con trỏ CHAR(STRING_ELT(chars, i), trong đó 0 < = i < chiều dài (ký tự), và lưu trữ nó trong s[i].

#include <stdlib.h> 
#include <Rinternals.h> 

SEXP test(SEXP chars) 
{ 
    int n, i; 
    char *s; 

    n = length(chars); 
    s = malloc(n + 1); 
    if (s != NULL) { 
     for (i = 0; i < n; i++) { 
     s[i] = *CHAR(STRING_ELT(chars, i)); 
     } 
     s[n] = '\0'; 
    } else { 
     /*handle malloc failure*/ 
    } 
    return R_NilValue; 
} 
6

Vectơ ký tự là STRSXP. Mỗi phần tử cá nhân là CHARSXP, vì vậy bạn cần một cái gì đó tương tự (chưa được kiểm tra):

const char *s; 
s = CHAR(STRING_ELT(chars, 0)); 

Xem Handling Character Data section of Writing R Extensions. Dirk sẽ sớm được giới thiệu với bạn về cách thức này sẽ dễ dàng hơn nếu bạn chỉ sử dụng C++ và Rcpp. :)

+0

Biểu thức 'CHAR (STRING_ELT (chars, 0))' chỉ cho tôi con trỏ đến ký tự đầu tiên (ký tự sau là '\ 0'). Để có được tất cả các ký tự, nó quay ra tôi cần phải lặp qua các ký tự (xem câu trả lời của tôi). –

2

Theo yêu cầu của Josh:

R> pickString <- cppFunction('std::string pickString(std::vector<std::string> invec, int pos) { return invec[pos]; } ') 
R> pickString(c("The", "quick", "brown", "fox"), 1) 
[1] "quick" 
R> 

C vectơ là zero-bù đắp, vì vậy 1 chọn phần tử thứ hai.

+0

Hoặc thậm chí ngắn gọn hơn: 'cppFunction ('Chuỗi pickString (CharacterVector invec, int pos) {return invec [pos];}')' (cppFunction hiện nhiệm vụ cho bạn) – hadley

+0

Có, nhưng OP là một lập trình viên C vì vậy tôi figured tôi muốn ở lại với các loại tiêu chuẩn và ẩn chúng ta. –

Các vấn đề liên quan