put_time是否支持输出无前缀单数字日期的转换说明符?
解决C++ put_time无法输出无填充日期的问题
我来帮你理清put_time里日期转换符的坑,以及对应的解决办法:
首先,put_time提供了两种日期转换说明符:
%d:带前导零的日期(01-31),比如1号会显示01%e:带前导空格的日期( 1-31),比如1号会显示1,10号及以上显示10-31
但尴尬的是,这两种都没法直接输出无填充的日期(也就是1-9号显示1-9,10号及以上正常显示)。就像你遇到的情况:想输出Feb 8 '18这种格式,用cout << put_time(&tmb, "%b%e '%y")的话,8号能得到Feb 8 '18,但到了10号就变成Feb10 '18——因为%e对10及以上的数字没有前导空格,导致月份和日期连在一起,格式就乱了。
这里给你两个实用的临时解决方案:
方案1:格式化后修正字符串
先通过put_time生成带前导零的格式,再手动去掉前导零:
#include <iostream> #include <iomanip> #include <sstream> #include <ctime> using namespace std; int main() { tm tmb = {}; // 设置测试日期:2018年2月8日 tmb.tm_year = 118; // 年份需减去1900 tmb.tm_mon = 1; // 0=1月,1=2月 tmb.tm_mday = 8; stringstream ss; // 先生成带前导零的格式,比如"Feb 08 '18" ss << put_time(&tmb, "%b %d '%y"); string result = ss.str(); // 定位日期位置,去掉前导零(如果有的话) size_t date_start = result.find(' ') + 1; if (result[date_start] == '0') { result.erase(date_start, 1); } cout << result << endl; // 输出:Feb 8 '18 // 测试10号的情况 tmb.tm_mday = 10; ss.str(""); ss << put_time(&tmb, "%b %d '%y"); result = ss.str(); date_start = result.find(' ') + 1; if (result[date_start] == '0') { result.erase(date_start, 1); } cout << result << endl; // 输出:Feb 10 '18 return 0; }
方案2:手动拼接日期组件
直接从tm结构体中提取月份、日期、年份,自己拼接成想要的格式:
#include <iostream> #include <iomanip> #include <ctime> #include <string> using namespace std; // 定义月份缩写数组 const string MONTH_ABBR[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; int main() { tm tmb = {}; tmb.tm_year = 118; tmb.tm_mon = 1; tmb.tm_mday = 8; // 直接拼接:月份缩写 + 空格 + 日期 + 单引号 + 两位年份 cout << MONTH_ABBR[tmb.tm_mon] << " " << tmb.tm_mday << " '" << setw(2) << setfill('0') << (tmb.tm_year % 100) << endl; // 输出:Feb 8 '18 // 测试10号 tmb.tm_mday = 10; cout << MONTH_ABBR[tmb.tm_mon] << " " << tmb.tm_mday << " '" << setw(2) << setfill('0') << (tmb.tm_year % 100) << endl; // 输出:Feb 10 '18 return 0; }
这两种方案都能解决put_time的格式局限,根据你的代码场景选就行~
内容的提问来源于stack exchange,提问作者Jonathan Mee
相关产品推荐
相关产品推荐

