我的目标是使用<iomanip>
设置50个左右的空格宽度,并<ctime>
打印日期和时间,但是这样做<iomanip>
不能按预期工作。我以同样的方式使用<iomanip>
,输出字符,用于以前的输出,它工作正常,所以我不确定我现在做错了什么。
// Example program
#include <iostream>
#include <string>
#include <ctime>
#include <iomanip>
using namespace std;
void dateTime(){
time_t now = time(0);
tm* dt = localtime(&now);
cout << setfill(' ') << setw(56) << left << 1900 + dt->tm_year << "/" << 1 + dt->tm_mon << "/" << dt->tm_mday << ", " << dt->tm_hour << ":" << dt->tm_min << " |" << endl;
}
int main()
{
dateTime();
}
输出我得到(不正确):
2016 /1/6, 17:36 |
预期输出(正确):
2016/1/6, 17:36 |
答案 0 :(得分:1)
问题是std::setw
仅影响一个输出的字段宽度,而不影响构成您关注的日期/时间的整个输出组。幸运的是,该标准提供了一种非常简洁的方法来处理问题:std::put_time
操纵器创建一个包含您关注的字段的结果,因此使用它,您可以将输出格式化为:
// Example program
#include <iostream>
#include <string>
#include <ctime>
#include <iomanip>
using namespace std;
void dateTime() {
time_t now = time(0);
tm* dt = localtime(&now);
std::cout << std::setw(56) << std::put_time(dt, "%Y/%m/%d, %H:%M") << "|";
}
int main()
{
dateTime();
}
...产生这样的输出:
2016/01/06, 17:48 |
答案 1 :(得分:0)
您可以定义自己的ignore_manipulator
流对象,以防止从iomanip
操纵输出。这是我在vrm_core, one of my C++14 libraries中的实现。
剥离实施:
struct ignore_manipulator
{
std::string _str;
ignore_manipulator(const std::string& str)
: _str(str)
{
}
auto& operator=(const std::string& str)
{
_str = str;
return *this;
}
operator const T&() const noexcept
{
return _str;
}
auto begin() const noexcept
{
return std::begin(_str);
}
auto end() const noexcept
{
return std::end(_str);
}
};
template <typename T>
auto operator<<(std::ostream& o, const ignore_manipulator& im)
{
// `o.put` ignores manipulators.
for(const auto& c : im) o.put(c);
return o;
}
用法示例:
// "hello" won't be affected by previous manipulators.
cout << setfill(' ') << setw(56) << ignore_manipulator("hello") << "\n";