从最多 X 个字符构造 std::string,在空字符处停止
Construct std::string from up to X characters, stopping at null char
我正在从文件中的结构中读取字符串,其中每个字符串都有固定长度,并带有 '[=12=]'
填充。如果存储的字符串需要整个长度,它们不是零终止的。
我目前正在用这样的东西构建 std::string
s:
// char MyString[1000];
std::string stdmystring(MyString, ARRAYSIZE(MyString));
但是,这也会复制填充。我现在可以 trim 字符串,但是有没有一种优雅而快速的方法来首先防止复制?
速度比space更重要,因为它是循环运行的。
简单的解决方案是:
先计算正确的长度
- 按照 Dieter 的建议使用
strnlen
- 或
std::find(MyString,MyString+ARRAYSIZE(MyString),'[=11=]')
IME 并不慢
请注意,如果您的字符串适合缓存,这可能会控制额外的循环成本
保留最大字符串大小(您确实说过 space 不太重要),并编写一个循环附加字符,直到您耗尽宽度或命中 nul(如 copy_until
)
实际创建一个用 nuls 初始化的最大大小的字符串,strncpy
放入其中,如果您希望大小正确,可以选择删除 unused
nuls
第二个选项只使用一个循环,而第三个选项名义上使用两个(它在字符串 ctor 中,然后在副本中)。然而,每个字符的 push_back
似乎比简单的字符分配更昂贵,所以如果 #3 在现实中更快,我不会感到惊讶。简介看看!
好吧,如果大小不是问题,一种可能的方法是创建一个空的 std::string
,然后使用 reserve()
预分配可能需要的 space,然后添加每个字符,直到遇到 '[=13=]'
.
std::string stdmystring;
stdmystring.reserve(MyString_MAX_SIZE) ;
for(size_t i=0;i<MyString_MAX_SIZE && MyString[i]!='[=10=]';++i);
stdmystring+=MyString[i];
reserve()
为您提供一个内存分配,因为您知道 max_size 并且字符串永远不会大于该值。
对 += 运算符函数的调用可能会被内联,但它仍然必须检查字符串是否具有所需的容量,这在您的情况下是浪费的。事实上,这可能与简单地使用 strlen 首先找到字符串的确切长度相同或更差,因此您必须对其进行测试。
我认为最直接的方法是将内部 MyString
数组过度分配一个字节,始终以 null 终止最后一个字节,并使用 std::string
的 C 字符串构造函数。 (请记住,您的进程很可能会 I/O 绑定到文件上,因此 C 字符串构造函数使用的任何算法都应该没问题)。
我正在从文件中的结构中读取字符串,其中每个字符串都有固定长度,并带有 '[=12=]'
填充。如果存储的字符串需要整个长度,它们不是零终止的。
我目前正在用这样的东西构建 std::string
s:
// char MyString[1000];
std::string stdmystring(MyString, ARRAYSIZE(MyString));
但是,这也会复制填充。我现在可以 trim 字符串,但是有没有一种优雅而快速的方法来首先防止复制?
速度比space更重要,因为它是循环运行的。
简单的解决方案是:
先计算正确的长度
- 按照 Dieter 的建议使用
strnlen
- 或
std::find(MyString,MyString+ARRAYSIZE(MyString),'[=11=]')
IME 并不慢
请注意,如果您的字符串适合缓存,这可能会控制额外的循环成本
- 按照 Dieter 的建议使用
保留最大字符串大小(您确实说过 space 不太重要),并编写一个循环附加字符,直到您耗尽宽度或命中 nul(如
copy_until
)实际创建一个用 nuls 初始化的最大大小的字符串,
strncpy
放入其中,如果您希望大小正确,可以选择删除unused
nuls
第二个选项只使用一个循环,而第三个选项名义上使用两个(它在字符串 ctor 中,然后在副本中)。然而,每个字符的 push_back
似乎比简单的字符分配更昂贵,所以如果 #3 在现实中更快,我不会感到惊讶。简介看看!
好吧,如果大小不是问题,一种可能的方法是创建一个空的 std::string
,然后使用 reserve()
预分配可能需要的 space,然后添加每个字符,直到遇到 '[=13=]'
.
std::string stdmystring;
stdmystring.reserve(MyString_MAX_SIZE) ;
for(size_t i=0;i<MyString_MAX_SIZE && MyString[i]!='[=10=]';++i);
stdmystring+=MyString[i];
reserve()
为您提供一个内存分配,因为您知道 max_size 并且字符串永远不会大于该值。
对 += 运算符函数的调用可能会被内联,但它仍然必须检查字符串是否具有所需的容量,这在您的情况下是浪费的。事实上,这可能与简单地使用 strlen 首先找到字符串的确切长度相同或更差,因此您必须对其进行测试。
我认为最直接的方法是将内部 MyString
数组过度分配一个字节,始终以 null 终止最后一个字节,并使用 std::string
的 C 字符串构造函数。 (请记住,您的进程很可能会 I/O 绑定到文件上,因此 C 字符串构造函数使用的任何算法都应该没问题)。