我如何从内存中读取,就像使用iostream的文件一样?

Mar*_*ski 7 c++ memory iostream

我有简单的文本文件加载到内存中.我想从内存中读取,就像我从像这里的光盘中读到的那样:

ifstream file;
string line;

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

但我有记忆中的档案.我在内存中有一个地址和这个文件的大小.

我必须做些什么才能获得与上述代码中处理文件相同的流畅度?

Nim*_*Nim 11

您可以执行以下操作..

std::istringstream str;
str.rdbuf()->pubsetbuf(<buffer>,<size of buffer>);
Run Code Online (Sandbox Code Playgroud)

然后在你的getline电话中使用它......

注意:getline不理解dos/unix的区别,所以\ r \n包含在文本中,这就是我为什么选择它的原因!

  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;
  }
Run Code Online (Sandbox Code Playgroud)

  • 此代码存在一个问题:无法保证可以正常工作.`pubsetbuf`对`basic_streambuf`的影响是"实现定义的".它还需要一个非const指针,因此它可以修改`putback`上的指向数据. (2认同)

det*_*zed 5

你可以用istringstream它.

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

while(file.good())
{
    getline(file,line);         
}
Run Code Online (Sandbox Code Playgroud)


ybu*_*ill 5

使用 boost.Iostreams。具体来说basic_array

namespace io = boost::iostreams;

io::filtering_istream in;
in.push(array_source(array, arraySize));
// use in
Run Code Online (Sandbox Code Playgroud)


Mar*_*ski 4

我找到了一个适用于 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:如果你有 '\r\n' 新行,就像 Nim 写的那样:

if (*line.rbegin() == '\r') line.erase(line.end() - 1);
Run Code Online (Sandbox Code Playgroud)

我试图将这段记忆视为wistream。有人知道怎么做这个吗?我为此提出了单独的问题。