这是一个老问题,我在过去观察到过。因此,我想一次得到一个澄清&一劳永逸。有许多标准/正统的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;
}在单元测试级别,它看起来似乎是有效的。但是对于我更大的代码中的整体日志来说,它不知何故变得一团糟。在此输出之后出现一个换行符&许多在此函数外部调用的输出字符串都不会打印出来。只有当"version-1“更改为"version-2”时,才会出现这种问题。
即使下面的修改也无济于事:
readable.resize(1 + std::strftime(&readable[0], readable.length(), "%Y-%h-%d %H:%M:%S:", &tm));我的代码中有什么错误吗?在C风格的字符串函数中直接使用std::string的正确方法是什么?
发布于 2017-02-01 18:57:14
std::string中可以包含\0。
所以
std::string s1 = "ab\0\0cd"; // s1 contains "ab" -> size = 2
std::string s2{"ab\0\0cd", 6}; // s2 contains "ab\0\0cd" -> size = 6第一个代码段使用构造函数1,而第二个类似于第二个(大小为30的字符串,其中填充了\0)。
因此,您必须正确调整字符串的大小,以避免拖尾\0。
发布于 2017-02-01 19:13:45
你的第一个函数是正确的。在第二个函数中浪费麻烦的细节是没有意义的,因为即使你做对了,它也不会比第一个函数有所改进。
事实上,它的性能甚至可能更差,因为需要过度分配字符串并调整其大小。例如,可能30的大小超过了小字符串优化的大小,但数据的实际长度不会。
https://stackoverflow.com/questions/41977630
复制相似问题