如何在处理传统C字符串的C样式函数中有效地使用std::string

How to use std::string effectively in the C-style functions which deals with conventional c-strings?

本文关键字:有效地 string std 函数 样式 处理 传统 字符串      更新时间:2023-10-16

这是一个老问题,我在过去观察过。所以想得到一次澄清&为所有人。有许多标准/正统的C库函数,它们只处理C风格的字符串。例如,我当前的实现如下:

std::string TimeStamp (const time_t seconds)  // version-1
{
auto tm = *std::localtime(&seconds);  // <ctime>
char readable[30] = {}; 
std::strftime(&readable[0], sizeof(readable) - 1, "%Y-%h-%d %H:%M:%S:", &tm);
return readable;
}

上述工作符合预期。但正如您所看到的,readable是从堆栈数组复制到std::string的。现在这个函数被频繁调用,用于记录&其他目的。

因此,我将其转换为以下内容:

std::string TimeStamp (const time_t seconds)  // version-2
{
auto tm = *std::localtime(&seconds);  // <ctime>
std::string readable(30,0);
std::strftime(&readable[0], readable.length(), "%Y-%h-%d %H:%M:%S:", &tm);
return readable;
}

在单元测试级别,它似乎可以工作。但对于我的大得多的代码的整体登录来说,它不知何故变得一团糟。在这个输出之后出现一个换行符&在该函数外部调用的许多输出字符串都没有打印出来。只有当"版本-1"更改为"版本-2"时,才会出现此类问题
即使以下修改也无济于事:

readable.resize(1 + std::strftime(&readable[0], readable.length(), "%Y-%h-%d %H:%M:%S:", &tm));

我的代码有什么错误吗?在C风格的字符串函数中直接使用std::string的正确方法是什么?

您的第一个函数是正确的。在第二个函数中处理麻烦的细节是没有意义的,因为即使你做对了,它也不会对第一个函数有所改进。

事实上,它甚至可能表现得更糟,因为需要过度分配字符串并向下调整其大小。例如,大小30可能超过了Small String Optimization的大小,但数据的实际长度没有。

std::string中可以有

所以

std::string s1 = "abcd";   // s1 contains "ab"       -> size = 2
std::string s2{"abcd", 6}; // s2 contains "abcd" -> size = 6

第一个代码段使用构造函数1,而第二个代码段与第二个类似(大小为30的字符串中填充了)。

因此,您必须正确调整字符串的大小,以避免遍历