题目
编写一个 C++ 程序,从标准输入读取圆的半径 r(双精度浮点数),计算圆的周长与面积。分别以默认流输出、保留 2 位小数(定点表示法 std::fixed + std::setprecision(2))以及科学计数法格式输出计算结果,并使用 std::setw 和 std::setfill 实现右对齐表格输出。
输入格式:一行输入一个浮点数,表示圆的半径 r。
输出格式:分行输出默认格式、定点保留 2 位小数、科学计数法以及带宽度填充的整齐格式。若半径小于 0,输出防御错误提示并退出。
数据范围与约定:<code>r ≥ 0.0</code>,双精度浮点数。
思路与算法
1. 流操纵符机制与持久性<iomanip> 中的操纵符多数具有黏性(Sticky),如 std::fixed 和 std::setprecision(n) 一旦作用于 std::cout,后续所有浮点输出均维持该格式,直到被 std::defaultfloat 复原;而 std::setw(w) 仅单次生效,下一次输出即恢复默认宽度。
2. 浮点输出模型对比
默认模式下,setprecision(n) 表示有效数字总位数(包括整数与小数部分);结合 std::fixed 后,setprecision(n) 严格表示小数点后的精确位数。科学计数法则使用 std::scientific 启用指数形式。
3. 对齐与填充字符
使用 std::left/std::right 配合 std::setw 和 std::setfill('.') 生成点阵报表。注意:setw 只对下一次插入生效,但 setfill 是黏性的,数字列若未改回空格也会用点号补齐;libstdc++ 按字节计宽,UTF-8 中文标签各占 6 字节。
完整程序
#include <iostream>
#include <iomanip>
#include <cmath>
int main() {
// 提升流 I/O 吞吐性能
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
double r = 0.0;
if (!(std::cin >> r) || r < 0.0) {
std::cout << "错误:请输入有效的非负半径数值。\n";
return 1;
}
const double pi = std::acos(-1.0);
double perimeter = 2.0 * pi * r;
double area = pi * r * r;
// 1. 默认流输出
std::cout << "--- 1. 默认输出 ---\n";
std::cout << "周长: " << perimeter << ", 面积: " << area << "\n\n";
// 2. 定点保留 2 位小数
std::cout << "--- 2. 定点保留2位小数 ---\n";
std::cout << std::fixed << std::setprecision(2);
std::cout << "周长: " << perimeter << "\n";
std::cout << "面积: " << area << "\n\n";
// 3. 科学计数法保留 4 位小数
std::cout << "--- 3. 科学计数法 ---\n";
std::cout << std::scientific << std::setprecision(4);
std::cout << "周长: " << perimeter << "\n";
std::cout << "面积: " << area << "\n\n";
// 4. 重置流状态并格式化对齐打印
std::cout << std::defaultfloat << std::setprecision(2) << std::fixed;
std::cout << "--- 4. 宽度对齐表格输出 ---\n";
std::cout << std::left << std::setw(10) << std::setfill('.') << "半径"
<< std::right << std::setw(12) << r << "\n";
std::cout << std::left << std::setw(10) << std::setfill('.') << "周长"
<< std::right << std::setw(12) << perimeter << "\n";
std::cout << std::left << std::setw(10) << std::setfill('.') << "面积"
<< std::right << std::setw(12) << area << "\n";
return 0;
}运行示例
输入:
5.5输出:
--- 1. 默认输出 ---
周长: 34.5575, 面积: 95.0332
--- 2. 定点保留2位小数 ---
周长: 34.56
面积: 95.03
--- 3. 科学计数法 ---
周长: 3.4558e+01
面积: 9.5033e+01
--- 4. 宽度对齐表格输出 ---
半径............5.50
周长...........34.56
面积...........95.03