gpt4 book ai didi

c++ - std::string.resize() 和 std::string.length()

转载 作者:太空狗 更新时间:2023-10-29 23:23:01 35 4
gpt4 key购买 nike

我是 C++ 的新手,但我仍在掌握 C++ 标准库。为了帮助从 C 转换,我想使用 printf 样式的格式化程序来格式化 std::string。我意识到 stringstream 是一种类型更安全的方法,但我发现自己发现 printf 风格更容易阅读和处理(至少目前是这样)。这是我的功能:


using namespace std;

string formatStdString(const string &format, ...)
{
va_list va;
string output;
size_t needed;
size_t used;

va_start(va, format);
needed = vsnprintf(&output[0], 0, format.c_str(), va);
output.resize(needed + 1); // for null terminator??
va_end(va);

va_start(va, format);
used = vsnprintf(&output[0], output.capacity(), format.c_str(), va);
// assert(used == needed);
va_end(va);

return output;
}

这很管用。我不确定的几件事是:

  1. 我是否需要为空终止符腾出空间,或者这是不必要的吗?
  2. capacity() 是在这里调用的正确函数吗?我一直认为 length() 会返回 0,因为字符串中的第一个字符是 '\0'

有时,在将此字符串的内容写入套接字时(使用其 c_str()length()),接收端会弹出空字节,这引起了一点悲伤,但它们似乎不一致。如果我根本不使用这个函数,则不会出现空字节。

最佳答案

使用当前标准(即将到来的标准在这里有所不同)不能保证由 std::string 管理的内部内存缓冲区将是连续的,或者 .c_str()方法返回指向内部数据表示的指针(允许实现为该操作生成一个连续的只读 block 并返回指向它的指针。可以使用 .data() 成员方法检索指向实际内部数据的指针,但请注意,它还返回一个常量指针:即它不是为了让您修改内容。.data()返回的缓冲区不一定是空终止,实现只需要保证当c_str()是空终止时调用,因此即使在调用 .data().c_str() 的实现中,实现也可以在调用后者时将 \0 添加到缓冲区的末尾。

该标准旨在允许绳索实现,因此原则上做您正在尝试的事情是不安全的,从标准的角度来看,您应该使用中间件 std::vector (保证连续性,并且保证 &myvector[0] 是指向实际缓冲区的第一个分配 block 的指针)。

在我所知道的所有实现中,内部存储器由 std::string 处理实际上是一个连续的缓冲区并使用 .data()是未定义的行为(写入常量变量)但即使不正确它也可能起作用(我会避免它)。您应该使用为此目的而设计的其他库,例如 boost::format .

关于空终止。如果您最终决定遵循未定义的路径...您将需要为空终止符分配额外的空间,因为库会将其写入缓冲区。现在,问题是与 C 风格的字符串不同,std::string s 可以在内部保存空指针,因此您必须调整字符串的大小以适应从一开始就不包含 \0 的最大连续内存块。 .这可能是您在使用虚假空字符时发现的问题。这意味着使用 vsnprintf 的错误方法(或家庭)必须后跟 str.resize( strlen( str.c_str() ) )在第一个 \0 之后丢弃字符串的所有内容.

总的来说,我会反对这种做法,坚持要么习惯C++的格式化方式,要么使用第三方库(boost是第三方的,但也是最标准的非标准库),要么使用vector或像在 C 中那样管理内存...但最后一个选项应该像瘟疫一样避免。

// A safe way in C++ of using vsnprintf:
std::vector<char> tmp( 1000 ); // expected maximum size
vsnprintf( &tmp[0], tmp.size(), "Hi %s", name.c_str() ); // assuming name to be a string
std::string salute( &tmp[0] );

关于c++ - std::string.resize() 和 std::string.length(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2880248/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com