`string.length()`的语义?

时间:2017-05-11 20:04:08

标签: c++

我想将已知大小的char缓冲区(例如从socket接收)转换为字符串,但是 需要注意的是char数组不一定是以null结尾的。

所以我尝试使用string (InputIterator first, InputIterator last)构造函数。 然而, 我注意到string::length()并不总是与strlen相同, 至少在我的情况下,字符串是从缓冲区手工制作的 有许多尾随零。

#include <string>
#include <iostream>

#include <string.h>

using namespace std;

int main()
{
    char a[20] {0};

    a[0] = 'a';
    string b(a, a + 20);
    cout << b.length() << endl;
    cout << strlen(b.c_str()) << endl;
}

输出

20
1

虽然这是string::length明确定义的行为(感谢评论和帮助我意识到的一些初步答案),但我希望找到一个更好/更惯用的解决方案。< / p>

2 个答案:

答案 0 :(得分:3)

这里的区别在于,对于std::string,这些NULL字符不会影响其长度;它可以很好地保持它们。

但是,对于c样式的字符串,strlen在遇到第一个NULL字符时会停止计数,对于你来说这是第二个字符,因此大小为1。

答案 1 :(得分:2)

你告诉它你想要20个字节,所以这正是你得到的。

听起来你想复制最多20个字节或直到遇到空字节

#include <string>
#include <iostream>
#include <cstring>

int main()
{
    char a[20]{};

    a[0] = 'a';
    std::string b(a, a + strnlen(a, sizeof(a)));
    std::cout << b.length() << '\n';
    std::cout << strlen(b.c_str()) << '\n';
}

你会注意到我已经回到让计算机检测到我们的输入字节数,但是strnlen可以告诉它在20处停止,处理数组<的问题em> may 不能以空值终止。

我已将{0}更改为{}style/sanity reasons

live demo