C++ 用memcpy填充std字符串不会设置长度

C++ 用memcpy填充std字符串不会设置长度,c++,curl,C++,Curl,我有以下代码用curl-get响应填充std::string struct curl_string { std::string tmpStr; size_t len; }; void init_string(struct curl_string *s) { s->len = 0; } size_t writefunc(void *ptr, size_t size, size_t nmemb, struct curl_string *s) { size_t

我有以下代码用curl-get响应填充
std::string

struct curl_string {
    std::string tmpStr;
    size_t len;
};

void init_string(struct curl_string *s) {
    s->len = 0;
}

size_t writefunc(void *ptr, size_t size, size_t nmemb, struct curl_string *s)
{
    size_t new_len = s->len + size*nmemb;
    s->tmpStr.reserve(new_len + 1);

    memcpy(&s->tmpStr[0] + s->len, ptr, size*nmemb);
    s->tmpStr[new_len] = '\0';
    s->len = new_len;

    return size*nmemb;
}
问题是,即使我保留了正确的长度,当我试图读回字符串时,大小仍然是0


我希望避免使用for循环一次添加1个字符。有没有办法做到这一点,但在
std::string
中仍然有正确的字符串长度?

您的问题是
std::string::reserve
只是为额外的字符保留内存,但实际上并没有改变字符串的长度。在修改基础缓冲区时,不会重新计算大小,因为在所有情况下几乎不可能检测到

解决方案是只使用
调整大小
而不是
保留

s->tmpStr.resize(new_len + 1);

是否有理由手动跟踪长度?您只需调用
s->tmpStr.size()

您的问题是
std::string::reserve
只为额外的字符保留内存,但实际上不会改变字符串的长度。在修改基础缓冲区时,不会重新计算大小,因为在所有情况下几乎不可能检测到

解决方案是只使用
调整大小
而不是
保留

s->tmpStr.resize(new_len + 1);

是否有理由手动跟踪长度?您只需调用
s->tmpStr.size()

要将传统字符串添加到std::string中,可以使用3种类型的成员函数

如果要替换,
assign
更好:

std::string str = "old text";
str.assign("new text", 8); // you can eliminate length
// str become "new text"
std::string str = "old text";
str.append(" new text", 9); // you can eliminate length
// str become "old text new text"
如果要插入字符串的结尾,
append
更好:

std::string str = "old text";
str.assign("new text", 8); // you can eliminate length
// str become "new text"
std::string str = "old text";
str.append(" new text", 9); // you can eliminate length
// str become "old text new text"
顺便说一下, 如果您的数据可能包含二进制,
我建议使用
std::vector
而不是
std::string

将传统字符串添加到std::string中,您可以使用3种类型的成员函数

如果要替换,
assign
更好:

std::string str = "old text";
str.assign("new text", 8); // you can eliminate length
// str become "new text"
std::string str = "old text";
str.append(" new text", 9); // you can eliminate length
// str become "old text new text"
如果要插入字符串的结尾,
append
更好:

std::string str = "old text";
str.assign("new text", 8); // you can eliminate length
// str become "new text"
std::string str = "old text";
str.append(" new text", 9); // you can eliminate length
// str become "old text new text"
顺便说一下, 如果您的数据可能包含二进制,
我推荐
std::vector
而不是
std::string

为什么需要单独的
len
成员?您可以使用获取有空间的字符数。另外,为什么要使用
memcpy
复制字符串?似乎
ptr
已经是一个
char
指针,所以只需将其转换为普通赋值。您不应该手动终止
std::string
对象。事实上,在您的例子中,您可以在一个简单的一行程序中完成这一切:
s->tmpStr=std::string(reinterpret_cast(ptr),nmemb)memcpy,是因为它是固定长度的二进制缓冲区,而不是以null结尾的字符串。为什么需要单独的
len
成员?您可以使用获取有空间的字符数。另外,为什么要使用
memcpy
复制字符串?似乎
ptr
已经是一个
char
指针,所以只需将其转换为普通赋值。您不应该手动终止
std::string
对象。事实上,在您的例子中,您可以在一个简单的一行程序中完成这一切:
s->tmpStr=std::string(reinterpret_cast(ptr),nmemb)memcpy,是因为它是固定长度的二进制缓冲区,而不是以null结尾的字符串。