Как я могу читать из памяти так же, как из файла с помощью iostream?

У меня есть простой текстовый файл, загруженный в память. Я хочу читать из памяти так же, как я читал бы с диска, как здесь:

ifstream file;
string line;

file.open("C:\\file.txt");
if(file.is_open())
{
    while(file.good())
    {
        getline(file,line);         
    }
}   
file.close();

Но у меня есть файл в памяти. У меня есть адрес в памяти и размер этого файла.

Что я должен делать, чтобы иметь такое же свободное владение, как и с файлом в коде выше?

Ответ 1

Я нашел решение, которое работает на VС++, поскольку решение Nim работает только на компиляторе GCC (большое спасибо, хотя. Благодаря вашему ответу я нашел другие ответы, которые помогли мне!).

Похоже, что у других людей тоже есть аналогичная проблема. Я сделал это как здесь и здесь.

Итак, чтобы прочитать из части памяти, как и форму istream, вы должны это сделать:

class membuf : public streambuf
{
    public:
        membuf(char* p, size_t n) {
        setg(p, p, p + n);
    }
};

int main()
{
    char buffer[] = "Hello World!\nThis is next line\nThe last line";  
    membuf mb(buffer, sizeof(buffer));

    istream istr(&mb);
    string line;
    while(getline(istr, line))
    {
        cout << "line:[" << line << "]" << endl;
    }
}

РЕДАКТИРОВАТЬ: И если у вас есть "\ r\n", новые строки делают, как писал Ним:

if (*line.rbegin() == '\r') line.erase(line.end() - 1);

Я пытаюсь обрабатывать эту память как wistream. Кто-нибудь знает, как это сделать? Я спросил об этом question.

Ответ 2

Вы можете сделать что-то вроде следующего.

std::istringstream str;
str.rdbuf()->pubsetbuf(<buffer>,<size of buffer>);

И затем используйте его в своих вызовах getline...

ПРИМЕЧАНИЕ. getline не понимает разницу dos/unix, поэтому \r входит в текст, поэтому я его сплюс!

  char buffer[] = "Hello World!\r\nThis is next line\r\nThe last line";  
  istringstream str;
  str.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
  string line;
  while(getline(str, line))
  {
    // chomp the \r as getline understands \n
    if (*line.rbegin() == '\r') line.erase(line.end() - 1);
    cout << "line:[" << line << "]" << endl;
  }

Ответ 3

Вы можете использовать istringstream для этого.

string text = "text...";
istringstream file(text);
string line;

while(file.good())
{
    getline(file,line);         
}

Ответ 4

Используйте boost.Iostreams. В частности basic_array.

namespace io = boost::iostreams;

io::filtering_istream in;
in.push(array_source(array, arraySize));
// use in

Ответ 5

Использование

std::stringstream

Он имеет интерфейс для манипулирования и чтения строк так же, как и другие потоки.

Ответ 6

Вот как бы я это сделал:

#include <sstream>

std::istringstream stream("some textual value");
std::string line;
while (std::getline(stream, line)) {
    // do something with line
}

Надеюсь, это поможет!