我想将已知大小的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>
答案 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。