Как прочитать файл Windows-1252 с помощью Rcpp?

Я хочу форсировать формат ввода при чтении файла в кодировке Windows-1252 вместе с Rcpp. Мне это нужно, так как я переключаюсь между средами Linux / Windows и в то время как файлы постоянно находятся в кодировке 1252.

Как мне адаптировать это к работе:

String readFile(std::string path) {
std::ifstream t(path.c_str());
if (!t.good()){
std::string error_msg = "Failed to open file ";
error_msg += "'" + path + "'";
::Rf_error(error_msg.c_str());
}

const std::locale& locale = std::locale("sv_SE.1252");
t.imbue(locale);
std::stringstream ss;
ss << t.rdbuf();
return ss.str();
}

Вышесказанное не работает с:

Error in eval(expr, envir, enclos) :
locale::facet::_S_create_c_locale name not valid

Я также попытался с «Swedish_Sweden.1252», который по умолчанию для моей системы, но безрезультатно. я пробовал #include <boost/locale.hpp> но это, кажется, недоступно в Rcpp (v 0.12.0) / BH boost (v. 1.58.0-1).

Обновить:

После более глубокого изучения этого вопроса я не уверен, что gcc (v. 4.6.3) в RTools (v. 3.3) построен с поддержкой локали, этот ТАК вопрос указывает на такую ​​возможность. Если есть какой-либо аргумент, кроме «» или «C», работает с std :: locale (), было бы интересно узнать, я пробовал еще несколько альтернатив, но, похоже, ничего не работает.

Резервное решение

Я не совсем доволен, но кажется, что использование base::iconv() исправляет любые проблемы с символами независимо от исходного формата, большое спасибо from="WINDOWS-1252"Аргумент, заставляющий символы интерпретироваться в правильной форме, т.е. если мы хотим остаться в Rcpp, мы можем просто сделать:

String readFile(std::string path) {
std::ifstream t(path.c_str());
if (!t.good()){
std::string error_msg = "Failed to open file ";
error_msg += "'" + path + "'";
::Rf_error(error_msg.c_str());
}

const std::locale& locale = std::locale("sv_SE.1252");
t.imbue(locale);
std::stringstream ss;
ss << t.rdbuf();
Rcpp::StringVector ret = ss.str();

Environment base("package:base");
Function iconv = base["iconv"];

ret = iconv(ret, Named("from","WINDOWS-1252"),Named("to","UTF8"));

return ret;
}

Обратите внимание, что предпочтительнее обернуть функцию в R, чем получать функцию из C ++ и затем вызывать ее оттуда, так как это меньше кода и улучшает улучшение производительности в 2 раза (проверено с помощью microbenchmark):

readFileWrapper <- function(path){
ret <- readFile(path)
iconv(ret, from = "WINDOWS-1252", to = "UTF8")
}

3

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]