相关疑难解决方法(0)

从(char*,size_t)创建C++内存流的简单方法,而不复制数据?

我找不到任何现成的东西,所以我想出了:

class membuf : public basic_streambuf<char>
{
public:
  membuf(char* p, size_t n) {
    setg(p, p, p + n);
    setp(p, p + n);
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

char *mybuffer;
size_t length;
// ... allocate "mybuffer", put data into it, set "length"

membuf mb(mybuffer, length);
istream reader(&mb);
// use "reader"
Run Code Online (Sandbox Code Playgroud)

我知道stringstream,但它似乎无法使用给定长度的二进制数据.

我在这里发明了自己的轮子吗?

编辑

  • 不能复制输入数据,只需创建迭代数据的东西.
  • 它必须是便携式的 - 至少它应该在gcc和MSVC下工作.

c++ memorystream

29
推荐指数
2
解决办法
5万
查看次数

C++:使用istream包装vector <char>

我想换一个vector<char>std::istream(所以读完载体将通过完成istream接口)

这样做的方法是什么?

c++

25
推荐指数
3
解决办法
1万
查看次数

设置标准流使用的内部缓冲区(pubsetbuf)

我正在编写一个需要将数据写入现有缓冲区的子程序,我想使用stringstream该类来简化数据的格式化.

最初,我使用以下代码将流的内容复制到缓冲区,但是希望避免这种解决方案,因为它复制了太多数据.

#include <sstream>
#include <algorithm>

void FillBuffer(char* buffer, unsigned int size)
{
    std::stringstream message;
    message << "Hello" << std::endl;
    message << "World!" << std::endl;

    std::string messageText(message.str());
    std::copy(messageText.begin(), messageText.end(), buffer);
}
Run Code Online (Sandbox Code Playgroud)

这是我发现streambuf::pubsetbuf()方法的时候,简单地重写上面的代码如下.

#include <sstream>

void FillBuffer(char* buffer, unsigned int size)
{
    std::stringstream message;
    message.rdbuf()->pubsetbuf(buffer, size);

    message << "Hello" << std::endl;
    message << "World!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这在Visual Studio 2008附带的C++标准库实现下不起作用; buffer保持不变.

我看了一下它的实现,pubsetbuf结果发现它实际上"什么都不做".

virtual _Myt *__CLR_OR_THIS_CALL setbuf(_Elem *, streamsize)
{   // offer buffer to external …
Run Code Online (Sandbox Code Playgroud)

c++ stream visual-c++

24
推荐指数
2
解决办法
2万
查看次数

非复制istringstream

因此istringstream,在初始化时复制字符串的内容,例如

string moo("one two three four");
istringstream iss(moo.c_str());
Run Code Online (Sandbox Code Playgroud)

我想知道是否有办法std::istringstream使用给定c_str的缓冲区而不复制东西.这样,在传递std::istringstream&istream&作为参数的函数之前,它不必复制大量内存.

我一直在努力做的是转换一些只接受std::ifstream&参数的函数(它们主要是解析器)istream&.我是否必须为此创建自己的istream子类?

c++ istream istringstream

11
推荐指数
2
解决办法
2869
查看次数

我如何从内存中读取,就像使用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)

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

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

c++ memory iostream

7
推荐指数
4
解决办法
7768
查看次数

用C++读取大字符串 - 是否有安全快速的方法?

http://insanecoding.blogspot.co.uk/2011/11/how-to-read-in-file-in-c.html回顾了在C++中将整个文件读入字符串的多种方法.最快选项的关键代码如下所示:

std::string contents;
in.seekg(0, std::ios::end);
contents.resize(in.tellg());
in.seekg(0, std::ios::beg);
in.read(&contents[0], contents.size());
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不安全,因为它依赖string于以特定方式实施.例如,如果实现是共享字符串,那么修改数据&contents[0]可能会影响正在读取的字符串之外的字符串.(更一般地说,不能保证这不会破坏任意记忆 - 在实践中不太可能发生,但依靠它不是好习惯.)

C++和STL旨在提供高效的C语言功能,因此可以预期上述版本的速度同样快,但保证安全.

在这种情况下vector<T>,有一些函数可用于访问原始数据,可用于有效地读取向量:

T* vector::data();
const T* vector::data() const; 
Run Code Online (Sandbox Code Playgroud)

其中第一个可以用来vector<T>有效地阅读.不幸的是,string等价物提供了const变体:

const char* string::data() const noexcept;
Run Code Online (Sandbox Code Playgroud)

所以这不能用于有效地读取字符串.(可能non-const省略了变体以支持共享字符串实现.)

我还检查了字符串构造函数,但接受char*复制数据的那些 - 没有选项可以移动它.

有没有一种安全快捷的方法将文件的全部内容读入字符串?

值得注意的是,我想读取一个string而不是一个,vector<char>以便我可以使用a来访问结果数据istringstream.没有相同的vector<char>.

c++ string stl file

6
推荐指数
1
解决办法
1159
查看次数