[英]Not sure why I am getting different lengths when using a string or a char
When I call gethostname using a char my length 25 but when I use a string my length is 64. Not really sure why. 当我使用char调用gethostname时,我的长度为25,但是当我使用字符串时,我的长度为64。不确定为什么。 Both of them I am declaring the same size on HOST_NAME_MAX. 我俩都在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();
An std::string
object can contain NUL
s (ie '\\0'
characters). 一个std::string
对象可以包含NUL
(即'\\0'
字符)。 You are storing the name in the first bytes of a string object that was created with a size of HOST_NAME_MAX
length. 您将名称存储在创建的字符串对象的前几个字节中,该字符串对象的长度为HOST_NAME_MAX
。
Storing something in the beginning of the string data won't change the length of the string that remains therefore HOST_NAME_MAX
. 在字符串数据的开头存储内容不会更改保留的字符串长度,因此为HOST_NAME_MAX
。
When creating a string from a char pointer instead the std::string
object created will contain up to, but excluding, the first NUL
character ( 0x00
). 当从char指针创建字符串时,创建的std::string
对象将最多包含但不包括第一个NUL
字符( 0x00
)。 The reason is that a C string cannot contain NUL
s because the first NUL
is used to mark the end of the string. 原因是C字符串不能包含NUL
因为第一个NUL
用于标记字符串的结尾。
Consider what you're doing in each case. 考虑每种情况下您正在做什么。 In the former code snippet, you're declaring a character array capable of holding HOST_NAME_MAX
-1 characters (1 for the null terminator). 在前一个代码段中,您声明了一个能够容纳HOST_NAME_MAX
-1个字符(空终止符为1个)的字符数组。 You then load some string data into that buffer via the call to gethostname
and then print out the length of buffer by assigning it to a std::string
object using std::string::operator=
that takes a const char *
. 然后,您可以通过调用gethostname
将一些字符串数据加载到该缓冲区中,然后使用std::string::operator=
将其分配给一个const char *
的std::string
对象,从而打印出缓冲区的长度。 One of the effects of this is that it will change an internal size variable of std::string
to be strlen
of the buffer, which is not necessarily the same as HOST_NAME_MAX
. 这样做的效果之一是它将更改内部大小变量std::string
为缓冲区的strlen
,它不一定与HOST_NAME_MAX
相同。 A call to std::string::length
simply returns that variable. 调用std::string::length
只会返回该变量。
In the latter case, you're using the std::string
constructor that takes a size and initial character to construct test
. 在后一种情况下,您使用的std::string
构造函数采用大小和初始字符来构造test
。 This constructor sets the internal size variable to whatever size you passed in, which is HOST_NAME_MAX
. 此构造函数将内部size变量设置为您传入的任何大小,即HOST_NAME_MAX
。 The fact that you then copy in some data to std::string
s internal buffer has no bearing on its size variable. 然后,您将一些数据复制到std::string
的内部缓冲区中,这一事实与它的size变量无关。 As with the other case, a call to the length()
member function simply returns the size - which is HOST_NAME_MAX
- regardless of whether or not the actual length of the underlying buffer is smaller than HOST_NAME_MAX
. 与其他情况一样,对length()
成员函数的调用仅返回大小HOST_NAME_MAX
而不管基础缓冲区的实际长度是否小于HOST_NAME_MAX
。
As @MattMcNabb mentioned in the comments, you could fix this by: 正如@MattMcNabb在评论中提到的那样,您可以通过以下方法解决此问题:
test.resize( strlen(test.c_str()) );
Why might you want to do this? 您为什么要这样做? Consistency with the char buffer approach might be a reason, but another reason may be performance oriented. 与char缓冲区方法的一致性可能是一个原因,但是另一个原因可能是面向性能的。 In the latter case you're not only outright setting the length of the string to HOST_NAME_MAX
, but also its capacity (omitting the SSO for brevity), which you can find starting on line 242 of libstdc++'s std::string implementation . 在后一种情况下,你不仅直接设置该字符串的长度HOST_NAME_MAX
, 而且其容量(省略了SSO为简洁起见),你可以找到在开始的242线的libstdc的std :: string实现++的 。 What this means in terms of performance is that even though only, say, 25 characters are actually in your test
string, the next time you append to that string (via +=
, std::string::append
,etc), it's more than likely to have to reallocate and grow the string, as shown here , because the internal size and internal capacity are equal. 就性能而言,这意味着即使test
字符串中实际上仅包含25个字符,下次您追加到该字符串时(通过+=
, std::string::append
等),它的性能仍然更高因为内部大小和内部容量相等,所以不必重新分配和增长字符串( 如此处所示) 。 Following @MattMcNabb's suggestion, however, the string's internal size is reduced down to the length of the actual payload, while keeping the capacity the same as before, and you avoid the almost immediate re-growth and re-copy of the string, as shown here . 但是,按照@MattMcNabb的建议,字符串的内部大小减小到实际有效负载的长度,同时保持容量与以前相同,并且避免了几乎立即重新增长和重新复制字符串, 如图所示在这里 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.