Как я могу читать из памяти так же, как из файла, используя iostream?
У меня есть простой текстовый файл, загруженный в память. Я хочу читать из памяти так же, как я бы читал с диска, как здесь:
ifstream file;
string line;
file.open("C:\\file.txt");
if(file.is_open())
{
while(file.good())
{
getline(file,line);
}
}
file.close();
Но у меня есть файл в памяти. У меня есть адрес в памяти и размер этого файла.
Что я должен сделать, чтобы иметь ту же беглость, что и при работе с файлом в коде выше?
6 ответов
Я нашел решение, которое работает на VC++, поскольку решение 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
, Кто-нибудь знает, как это сделать? Я задал отдельный вопрос для этого.
Вы можете сделать что-то вроде следующего..
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;
}
Ты можешь использовать istringstream
для этого.
string text = "text...";
istringstream file(text);
string line;
while(file.good())
{
getline(file,line);
}
Используйте boost.Iostreams. конкретно basic_array
,
namespace io = boost::iostreams;
io::filtering_istream in;
in.push(array_source(array, arraySize));
// use in
Использование
std::stringstream
Он имеет интерфейс для манипулирования и чтения строк, как и другие потоки.
Вот как бы я это сделал:
#include <sstream>
std::istringstream stream("some textual value");
std::string line;
while (std::getline(stream, line)) {
// do something with line
}
Надеюсь это поможет!