使用C++20 std::format
和 {:.2}
代替 std::setprecision
最终,一旦你能使用它,这将是更优的选择:
#include <format>
#include <string>
int main() {
std::cout << std::format("{:.3} {:.4}\n", 3.1415, 3.1415);
}
预期输出:
3.14 3.145
所以这将完全克服修改 std::cout
状态的疯狂。
现有的 fmt
库实现了它,早在它正式获得支持之前:https://github.com/fmtlib/fmt 在 Ubuntu 22.04 上安装:
sudo apt install libfmt-dev
修改源代码以替换:
<format>
为 <fmt/core.h>
std::format
为 fmt::format
main.cpp
#include <iostream>
#include <fmt/core.h>
int main() {
std::cout << fmt::format("{:.3} {:.4}\n", 3.1415, 3.1415);
}
并且使用以下命令进行编译和运行:
g++ -std=c++11 -o main.out main.cpp -lfmt
./main.out
输出:
3.14 3.142
参见:
在C++20之前/fmt::
:使用std::ios::copyfmt
保存整个状态
在这些情况下,您可能还想使用std::ios::copyfmt
恢复整个以前的状态,如恢复操作std::cout后的其状态所述。
main.cpp
#include <iomanip>
#include <iostream>
int main() {
constexpr float pi = 3.14159265359;
constexpr float e = 2.71828182846;
std::cout << "default" << std::endl;
std::cout << pi << std::endl;
std::cout << e << std::endl;
std::cout << std::endl;
std::cout << "modified" << std::endl;
std::ios cout_state(nullptr);
cout_state.copyfmt(std::cout);
std::cout << std::setprecision(2);
std::cout << std::scientific;
std::cout << pi << std::endl;
std::cout << e << std::endl;
std::cout.copyfmt(cout_state);
std::cout << std::endl;
std::cout << "restored" << std::endl;
std::cout << pi << std::endl;
std::cout << e << std::endl;
std::cout << std::endl;
}
GitHub源代码。
编译并运行:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
输出:
default
3.14159
2.71828
modified
3.14e+00
2.72e+00
restored
3.14159
2.71828
在Ubuntu 19.04和GCC 8.3.0上进行了测试。