能否直接将内容保留并复制到std::string中?

4

能否预留空间在std::string中并获得指向它的指针以直接复制char数据到其中? 我必须与返回通过将其复制到char*中的字符串的C库进行接口。 如何设置std::string以便库可以直接写入它,避免中间复制。

以下是此示例的假设性示例:

std::string mystring;
int strlen = foolib_get_string_size(fooval);
mystring.size(strlen); // assuming size() with arg exists and does reserve() and set size
foolib_string_to_char_buffer(fooval, mystring.data(), strlen); // abusing data() method for writing

3
你需要的是 mystring.resize(strlen);,而不是 mystring.size(strlen); - kesarling He-Him
这个回答解决了你的问题吗?如何直接从char*数组创建std::string而不进行复制? - g19fanatic
1
@g19fanatic:内容确实是同一个问题,但标题有误导性(暗示了一个_已存在的_ char * 数组)。这就是为什么它没有出现在搜索结果中的原因。 - diemo
虽然您的标题对我来说不太清楚。 - g19fanatic
1个回答

4

是否可以在std :: string中保留空间并获取指向它的指针,以直接将char数据复制到其中?

是的。使用其resize()方法来分配内存,然后使用其data()方法(C++17及以上版本),或其operator [],来访问该内存。

我必须与返回通过将它们复制到char *中的字符串的C库进行接口。如何设置std :: string,以使库可以直接写入其中,避免中间副本。

像这样:

std::string mystring;
int strlen = foolib_get_string_size(fooval);
if (strlen > 0)
{
    mystring.resize(strlen); // -1 if strlen includes space for a null terminator
    foolib_string_to_char_buffer(fooval, mystring.data()/*&mystring[0]*/, strlen);
}

或者,std::string也可以使用构造函数来分配内存:

int strlen = foolib_get_string_size(fooval);
std::string mystring(strlen, '\0'); // -1 if strlen includes space for a null terminator
if (strlen > 0)
    foolib_string_to_char_buffer(fooval, mystring.data()/*&mystring[0]*/, strlen);

当然,这需要std::string的内存块是连续分配的,这只在C++11及以后版本中得到保证(但实际上,在几乎所有已知的实现中都是这样做的)。如果您没有使用C++11或更高版本,并且确实想符合标准,则应使用中间缓冲区,例如std::vector,例如:
std::string mystring;
int strlen = foolib_get_string_size(fooval);
if (strlen > 0)
{
    std::vector<char> myvector(strlen);
    foolib_string_to_char_buffer(fooval, &myvec[0], strlen);
    mystring.assign(&myvec[0], strlen); // -1 if strlen includes space for a null terminator
}

谢谢!所以简短的回答似乎是:自C++11起,可以通过&mystring[0]实现,而自C++17起则正式通过data()实现。 - diemo
2
@diemo 更确切的说,在C++11之前是原则上可以这么做,通过&mystring[0]来实现;而在C++11中已正式支持;在C++17中则可以通过mystring.data()来实现。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接