У меня есть код, который использует ifstream
читать некоторые данные из файла, и все работает.
Теперь я хочу, не изменяя некоторый код, прочитать эти данные из памяти, на самом деле у меня есть char *
который содержит данные …
Как я могу поставить свой char *
данные в ifstream
не читая эффективно файл?
Если код, который использует ifstream&
можно немного изменить, чтобы использовать istream&
тогда вы могли бы легко переключаться между ifstream
а также istringstream
(для чтения данных из памяти):
void read_data(std::istream& in)
{
}
Вызывающие:
std::istringstream in_stream(std::string("hello"));
read_data(in_stream);
std::ifstream in_file("file.txt");
read_data(in_file);
Стандартная библиотека предлагает в памяти istream
это также доступно для записи: std::stringstream
.
Вы должны правильно абстрагировать свой код, чтобы он принимал общий istream
вместо ifstream
построить stringstream
, заполните его своими данными и передайте это функции.
Например:
const char* data = "Hello world";
std::stringstream str((std::string(data))); // all the parens are needed,
// google "most vexing parse"
do_something_with_istream(str); // pass stream to your code
Хотя использование std::istringstream
(иногда ошибочно упоминается с ведущими i
; такой класс тоже существует, но его создание дороже, так как он также создает выходной поток) очень популярен, я думаю, стоит отметить, что это делает, по крайней мере, одну копию фактической строки (I ‘ Я подозреваю, что большинство реализаций создают даже две копии). Создание любой копии можно избежать, используя тривиальный буфер потока:
struct membuf: std::streambuf {
membuf(char* base, std::ptrdiff_t n) {
this->setg(base, base, base + n);
}
};
membuf sbuf(base, n);
std::istream in(&sbuf);
Для небольшой области памяти разница может не иметь значения, хотя сохраненное выделение может быть заметным и там. Для больших кусков памяти это имеет большое значение.
Вы можете искать поток строк. http://www.cplusplus.com/reference/sstream/stringstream/. Я использовал это только один раз, и это было давно, но в основном вы можете транслировать из места в памяти.
В моем проекте я использую методы write () и read () iostream, поскольку я записываю двоичные данные в поток строк. Извините, следующий код не тестировался и, возможно, имеет синтаксические ошибки (набирает из офиса … ;-), но что-то вроде этого позволяет записывать в память, файлы и другие места (например, сетевые сокеты):
void foo(std::iostream *mystream)
{
mystream.write("Hello", 5);
uint32_t i=5302523;
mystream.write((char*) &i, sizeof i);
}
int main()
{
// Write to memory. stringstream's write() and read() work binary
std::stringstream memstream;
foo(&memstream);
// Write to file
std::fstream f;
try
{
f.open("file.dat");
foo(&f);
}
catch (...)
{
// ...
}
if (f.is_open())
f.close();
return EXIT_SUCCESS;
}