直接从 std::istream 读取到 std::string
无论如何,是否可以将已知数量的字节直接读取到 std::string 中,而不创建临时缓冲区来执行此操作?
例如目前我可以这样做
boost::uint16_t len;
is.read((char*)&len, 2);
char *tmpStr = new char[len];
is.read(tmpStr, len);
std::string str(tmpStr, len);
delete[] tmpStr;
Is there anyway to read a known number of bytes, directly into an std::string, without creating a temporary buffer to do so?
eg currently I can do it by
boost::uint16_t len;
is.read((char*)&len, 2);
char *tmpStr = new char[len];
is.read(tmpStr, len);
std::string str(tmpStr, len);
delete[] tmpStr;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
std::string
有一个可以使用的resize
函数,或者一个可以执行相同操作的构造函数:这是未经测试的,我不知道字符串是否是强制的拥有连续的存储空间。
std::string
has aresize
function you could use, or a constructor that'll do the same:This is untested, and I don't know if strings are mandated to have contiguous storage.
您可以使用 copy_n 和 insert_iterator 的组合
,没有复制,没有黑客,没有溢出的可能性,没有未定义的行为。
You could use a combination of copy_n and an insert_iterator
no copying, no hacks, no possibility of overrun, no undefined behaviour.
我会使用向量作为缓冲区。
尽管您可能会使用字符串作为缓冲区(如 GMan 所描述的)。标准不保证字符串成员位于连续位置(因此请检查当前的实现并添加一个大注释,表明在移植到另一个编译器/平台时需要检查)。
I would use a vector as the buffer.
Though you will probably get away with using a string as the buffer (as described by GMan). It is not guaranteed by the standard that a strings members are in consecutive locations (so check your current implementation and put a big comment that it needs checking when porting to another compiler/platform).
你可以使用像 getline 这样的东西:
You could use something like getline:
您只是优化代码长度还是想在这里保存一份副本?临时缓冲区出了什么问题?
我认为你实际上是在规避字符串的保护,试图直接这样写。如果您担心复制到 std::string 的性能,因为您已经确定它在某种程度上影响应用程序的性能,那么我会直接使用 char*。
编辑:做更多的事情......
从 char* 初始化 std::string 而不复制
在第二个答案中,它是非常明确地指出,您无法实现您想要实现的目标(即填充 std::string 而不对 char* 进行迭代来复制。)
看看您的加载例程(也许将其发布在这里?)并最小化分配:new 和delete 当然不是免费的,所以如果您不必不断地重新创建缓冲区,您至少可以节省一些时间。我总是发现通过将缓冲区 memset 为 0 或 null 终止每次迭代的数组的第一个索引来擦除它很有帮助,但是一旦您对算法充满信心,您可以为了性能而快速消除该代码。
Are you just optimizing code length or trying to save yourself a copy here? What's wrong with the temporary buffer?
I'd argue that you're actually circumventing the protections of the string trying to write directly do it like that. If you're worried about performance of the copy to a std::string because you've identified that it's in some way affecting the performance of your application, I'd work directly with the char*.
EDIT: Doing more looking...
initializing std::string from char* without copy
In the second answer, it's stated pretty flatly that you can't achieve what you're looking to achieve (ie. populate a std::string without an iteration over the char* to copy.)
Take a look at your load routine (post it here perhaps?) and minimize allocations: new and delete certainly aren't free so you can at least save some time if you don't have to re-create the buffer constantly. I always find it helpful erase it by memset'ing the buffer to 0 or null terminating the first index of the array each iteration but you may quickly eliminate that code in the interests of performance once you're confident in your algorithm.
一个简单的方法是:
An easy way would be: