有没有一种方法可以设置std :: string的长度而不修改缓冲区内容? [英] is there a way to set the length of a std::string without modifying the buffer content?

查看:92
本文介绍了有没有一种方法可以设置std :: string的长度而不修改缓冲区内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据这些问题的答案中的陈述

According to the statements made in the answers of these questions

..在C ++ 11中,应该可以调用C API函数,该函数需要一个char指针来存储输出,如下所示:

.. in C++11 it should be possible to call a C API function which takes a char pointer to store the output like this:

str::string str;
str.reserve(SOME_MAX_VALUE);
some_C_API_func(&str[0]);

但是现在是否有一种合法的方法来设置字符串的大小为缓冲区内(空终止)内容的长度?像这样:

But is there now a legal way to set the size of the string to the length of the (null terminated) content inside the buffer? Something like this:

str.set_size(strlen(&str[0]));

无论如何,这都是对 std :: string 的一种非常绝妙的滥用,尽管我听到您说过,但是我无法在堆栈上创建一个临时的 char 缓冲区,所以我会在堆中创建一个缓冲区,然后销毁它(我想避免).

This is a very unaesthetic abuse of std::string anyway I hear you say, but I can't create a temporary char buffer on stack so I would have to create a buffer in heap and destroy it afterwards (which I want to avoid).

有没有很好的方法可以做到这一点?也许不保留,但可以调整大小并在之后调用 erase()即可,但是感觉不太整洁.

Is there a nice way to do this? Maybe not reserving but resizing and calling erase() afterwards would do it but it doesn't feel nice neater..

推荐答案

您应该使用 resize()而不是 reserve(),然后使用 resize()再次设置最终长度.

You should be using resize() not reserve(), then resize() again to set the final length.

否则,当您将 size()从零调整为 strlen()返回的结果时,该数组将填充零个字符,从而覆盖您在其中写入的内容.允许使用该字符串,因为它(正确地)假定从当前大小到当前保留容量的所有内容都是未包含任何内容的未初始化数据.

Otherwise when you resize() from zero to the result returned by strlen() the array will be filled with zero characters, overwriting what you wrote into it. The string is allowed to do that, because it (correctly) assumes that everything from the current size to the current reserved capacity is uninitialized data that doesn't contain anything.

为了使字符串知道字符实际上是有效的并且应该保留其内容,您需要首先使用 resize(),而不是 reserve().然后,当您再次 resize()以减小字符串长度时,它只会截断字符串的多余部分并添加一个空终止符,它不会覆盖您在其中写入的内容.

In order for the string to know that the characters are actually valid and their contents should be preserved, you need to use resize() initially, not reserve(). Then when you resize() again to make the string smaller it only truncates the unwanted end of the string and adds a null terminator, it won't overwrite what you wrote into it.

最初的 resize()将对字符串进行零填充,在您的情况下,这并不是严格必需的,因为您将覆盖您关心的部分,然后将其余部分丢弃.如果字符串很长并且分析显示填零是一个问题,那么您可以这样做:

N.B. the initial resize() will zero-fill the string, which is not strictly necessary in your case because you're going to overwrite the portion you care about and then discard the rest anyway. If the strings are very long and profiling shows the zero-filling is a problem then you could do this instead:

std::unique_ptr<char[]> str(new char[SOME_MAX_VALUE]);
some_C_API_func(str.get());

这篇关于有没有一种方法可以设置std :: string的长度而不修改缓冲区内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆