Конвертировать FILE * в ifstream C ++, Android NDK

Я кодирую проект Android с компонентом NDK C ++, и у меня есть файл, который нуждается в большом разборе. NDK позволяет мне только получить указатель FILE * на файл, с которым я имею дело, а не ifstream, с которым связано еще несколько вспомогательных функций. Есть ли способ конвертировать FILE * (cstdio) в ifstream (iostream)?

3

Решение

В общем, вы можете не преобразовать FILE* для std::ifstream, Тем не менее, в любом случае это не обязательно: разумно прямо сейчас создать собственный буфер потока, который можно использовать для инициализации std::istream, Используя std::istream должно быть достаточно, потому что дополнительная функциональность, предоставляемая std::ifstream на самом деле не помогает с разбором. Пока вам не нужно использовать поиск, создание потокового буфера для чтения из FILE* это действительно просто. Все, что нужно, это переопределить std::streambuf::underflow() функция:

class stdiobuf
: std::streambuf
{
private:
FILE* d_file;
char  d_buffer[8192];
public:
stdiobuf(FILE* file): d_file(file) {}
~stdiobuf() { if (this->d_file) fclose(this->d_file); }
int underflow() {
if (this->gptr() == this->egptr() && this->d_file) {
size_t size = fread(this->d_file, 8192);
this->setg(this->d_buffer, this->d_buffer, this->d_buffer + size);
}
return this->gptr() == this->egptr()
? traits_type::eof()
: traits_type::to_int_type(*this->gptr());
}
};

Осталось только инициализировать std::istream использовать stdiobuf:

stdiobuf     sbuf(fopen(...));
std::istream in(&sbuf);

Я просто набрал код выше и в настоящее время не могу его опробовать. Тем не менее, основные должны быть правильными, хотя могут быть типы и, возможно, даже небольшой недостаток.

5

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

Обратите внимание, что нет способа получить std::ifstream, но ты Можно получить std::istream,

Хотя не является частью стандартного C ++, иногда std::basic_filebuf выставляет расширение через конструктор, который принимает std::FILE *.

basic_filebuf(FILE *fp, char_type *buf = 0,
streamsize n = /* default size */);

Создает объект класса basic_filebuf, инициализируя базовый класс с basic_streambuf<charT,traits>(), Затем звонит open(fp, buf, n),

Как вы должны использовать это следующим образом …

FILE *pf = ...; /* e.g. fopen("/etc/passwd", "r") */
std::filebuf buf(pf);
std::istream stream(&buf);

Теперь, если это расширение недоступно, то, боюсь, вы мало что можете сделать, кроме как попытаться реализовать собственное std::streambuf который реализует требуемую работу.

3

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