[英]Not sure why I am getting different lengths when using a string or a char
当我使用char调用gethostname时,我的长度为25,但是当我使用字符串时,我的长度为64。不确定为什么。 我俩都在HOST_NAME_MAX上声明了相同的大小。
char hostname[HOST_NAME_MAX];
BOOL host = gethostname(hostname, sizeof hostname);
expectedComputerName = hostname;
int size2 = expectedComputerName.length();
std::string test(HOST_NAME_MAX, 0);
host = gethostname(&test[0], test.length());
int testSize = test.length();
一个std::string
对象可以包含NUL
(即'\\0'
字符)。 您将名称存储在创建的字符串对象的前几个字节中,该字符串对象的长度为HOST_NAME_MAX
。
在字符串数据的开头存储内容不会更改保留的字符串长度,因此为HOST_NAME_MAX
。
当从char指针创建字符串时,创建的std::string
对象将最多包含但不包括第一个NUL
字符( 0x00
)。 原因是C字符串不能包含NUL
因为第一个NUL
用于标记字符串的结尾。
考虑每种情况下您正在做什么。 在前一个代码段中,您声明了一个能够容纳HOST_NAME_MAX
-1个字符(空终止符为1个)的字符数组。 然后,您可以通过调用gethostname
将一些字符串数据加载到该缓冲区中,然后使用std::string::operator=
将其分配给一个const char *
的std::string
对象,从而打印出缓冲区的长度。 这样做的效果之一是它将更改内部大小变量std::string
为缓冲区的strlen
,它不一定与HOST_NAME_MAX
相同。 调用std::string::length
只会返回该变量。
在后一种情况下,您使用的std::string
构造函数采用大小和初始字符来构造test
。 此构造函数将内部size变量设置为您传入的任何大小,即HOST_NAME_MAX
。 然后,您将一些数据复制到std::string
的内部缓冲区中,这一事实与它的size变量无关。 与其他情况一样,对length()
成员函数的调用仅返回大小HOST_NAME_MAX
而不管基础缓冲区的实际长度是否小于HOST_NAME_MAX
。
正如@MattMcNabb在评论中提到的那样,您可以通过以下方法解决此问题:
test.resize( strlen(test.c_str()) );
您为什么要这样做? 与char缓冲区方法的一致性可能是一个原因,但是另一个原因可能是面向性能的。 在后一种情况下,你不仅直接设置该字符串的长度HOST_NAME_MAX
, 而且其容量(省略了SSO为简洁起见),你可以找到在开始的242线的libstdc的std :: string实现++的 。 就性能而言,这意味着即使test
字符串中实际上仅包含25个字符,下次您追加到该字符串时(通过+=
, std::string::append
等),它的性能仍然更高因为内部大小和内部容量相等,所以不必重新分配和增长字符串( 如此处所示) 。 但是,按照@MattMcNabb的建议,字符串的内部大小减小到实际有效负载的长度,同时保持容量与以前相同,并且避免了几乎立即重新增长和重新复制字符串, 如图所示在这里 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.