如何根据时间格式指定std::strftime的缓冲区大小?
动态调整std::strftime的缓冲区大小方案
先提个小细节:你的代码里用了localtime_r,这是把时间戳转成本地时间,如果要实现需求里的UTC时间转换,应该替换成gmtime_r。
回到你的核心疑问:完全可以根据时间格式动态指定缓冲区大小,下面是两种实用方案:
方案一:利用strftime的返回值动态分配缓冲区
std::strftime有个关键特性:当传入的缓冲区大小为0时,它不会写入任何内容,而是直接返回格式化后字符串所需的字节数(不含末尾的\0)。基于这个特性,我们可以先调用一次获取所需长度,再动态分配缓冲区。
修改后的代码如下:
#include <ctime> #include <cstdint> #include <string> #include <vector> std::string convert_timestamp_to_utc(const std::uint64_t timestamp) { const std::time_t time_stamp = static_cast<std::time_t>(timestamp); struct tm buf{}; // 替换为gmtime_r生成UTC时间结构 if (gmtime_r(&time_stamp, &buf) == nullptr) { return {}; } const char* format = "%c"; // 先获取格式化所需的缓冲区长度 std::size_t required_size = std::strftime(nullptr, 0, format, &buf); if (required_size == 0) { return {}; } // 动态分配缓冲区,+1用于存储终止符 std::vector<char> time_buf(required_size + 1); if (std::strftime(time_buf.data(), time_buf.size(), format, &buf) != 0) { return std::string(time_buf.data()); } return {}; }
方案二:用C++17的std::format替代strftime(更简洁)
如果你的项目支持C++17及以上,推荐使用<format>库,它不需要手动管理缓冲区,直接生成std::string,代码更简洁安全:
#include <ctime> #include <cstdint> #include <string> #include <format> std::string convert_timestamp_to_utc(const std::uint64_t timestamp) { const std::time_t time_stamp = static_cast<std::time_t>(timestamp); struct tm buf{}; if (gmtime_r(&time_stamp, &buf) == nullptr) { return {}; } // std::format的时间格式符与strftime兼容,用"{:%c}"对应原格式的"%c" return std::format("{:%c}", buf); }
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

