【发布时间】:2018-01-22 13:21:58
【问题描述】:
我正在尝试在现有的 std::stringbuf 对象前添加一个 4 字节的标头。例如,如果 stringbuf 中的数据是 ‘h’,’e’,’l’,’l’,’o’ 并且标头是 ‘0x00’,’0x10’, ‘0x00’,’0x0a’ 那么我需要将 stringbuf 更改为 ‘0x00’,’0x10’, ‘0x00’,’0x0a’, ‘h’,’e’,’l’,’l’,’o’。
我一直在尝试下面的方法,但它效率低下,因为它在sbuf、TextStream 和 buff 中有三个数据副本。使用new char[] 问题更大,因为它需要连续的内存块,而且我可以拥有非常大的流。
有人可以通过向我展示如何以更好的优化方式来帮助我吗?我的意思是有没有办法在现有的 stringbuf 之前添加字节?
std::stringbuf CreateStreamWithHeader(std::stringbuf &sbuf)
{
int i = sbuf.str().size();
std::stringbuf TextStreambuf;
uint32_t streamsize = sbuf.str().size();
char* buff = new char [streamsize + 5]; //Using char buffer is not memory efficient as it needs a big contonuous chunk of memory.
ZeroMemory(buff, (streamsize + 5)*sizeof(char));
buff[0] = (streamsize >> 24) & 0xFF; //In my case header needs to contain size of data in sbuf
buff[1] = (streamsize >> 16) & 0xFF;
buff[2] = (streamsize >> 8) & 0xFF;
buff[3] = (streamsize >> 0) & 0xFF;
strcpy(&buff[4], sbuf.str().c_str()); //strcpy is not the right solution because it will fail if there’s a NULL character in sbuf
memcpy(&buff[4], sbuf.str().c_str(), streamsize);
TextStreambuf.sputn(buff, streamsize + 4);
delete []buff;
return TextStreambuf;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::stringbuf stringbuffer, finalstringbuffer;
stringbuffer.sputn("This is a some string for testing", 33);
finalstringbuffer = CreateStreamWithHeader(stringbuffer);
return 0;
}
【问题讨论】:
-
出于好奇,您为什么在 C++ 中使用
stringbuf而不仅仅是普通的string? -
您要解决的实际问题是什么?该答案的一部分应包括这些字节的用途。
-
我在加密数据时这样做。数据的前 4 个字节需要包含原始数据的大小。实际进行加密的 proc(不是我写的)接受 stringbuf,所以我也在使用它。
-
我以前没有使用过 stringbuf,但我认为它不是连续的内存块,而字符串是连续的内存块,这意味着如果需要在字符串前面添加任何内容,则需要整个字符串复制到新位置或所有字节都需要移动。我想如果我可以在流之前添加字节,我会很好吗?由于 stringbuf 是 stringstream 的底层缓冲区,我可以从 stringstream 获取 stringbuf。
标签: c++ stl stream buffer stringstream