简体   繁体   English

不知道为什么使用字符串或char时会得到不同的长度

[英]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.

相关问题 为什么我会从此字符串到char转换中获得随机输出? - Why am I getting random outputs from this string to char conversion? 为什么在对同一个字符数组使用 sizeof 时会得到不同的结果? - Why I am getting varied results when using sizeof for same char array? 我不确定为什么要为此得到输出? - I am not sure why I am getting output for this? 当使用相似的逻辑递增两种不同的指针类型时,为什么会得到不同的地址? - Why am I getting different addresses when using similar logic to increment two different pointer types? 为什么我在使用&这时会出错? - Why am I getting an error when using &this? 我一直收到语法错误,但我不确定原因 - I keep getting a syntax error but I am not sure why 为什么我收到错误:无法转换 &#39;std::string {aka std::basic_string<char> }&#39; 到 &#39;char*&#39; 赋值? - Why am I getting error: cannot convert ‘std::string {aka std::basic_string<char>}’ to ‘char*’ in assignment? 不知道为什么我在 cin 和 getline 中出现 C++ 错误 - Not sure why I am getting C++ error with cin and getline 为什么在尝试将opencv图像数据指针转换为char *时出现错误? - Why I am getting error when I try to cast an opencv image data pointer to a char* 为什么我在 char 数组的末尾得到 i? - why I am getting i at the end of char array?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM