C++ 格式化输入输出
格式化输入输出是C++中非常重要的功能,它让我们能够按照特定格式显示数据或从用户输入中读取数据。下面我将从基本概念、格式化输出和格式化输入三个方面详细讲解。
一、总述
在C++中,主要通过两种方式实现格式化输入输出:
- 使用成员函数或全局函数
- 使用流操纵符(manipulators)
1.1 成员函数
C++的输入输出都属于流对象,各种方式的格式化本质上都是通过成员函数来实现的。
precision(n): 设置浮点数的输出精度。fill(ch):设置填充字符。width(n):设置输出宽度。setf(fmtflags):设置格式标志。fmtflags为格式化标志,可以是多个标志的组合。通过命名空间std::ios引用。setf(fmtflags, mask):清除原有格式标志,设置新的格式标志。mask为格式重置标志,只有3个(adjustfield、basefield、floatfield)。flags为要设置的格式标志。unsetf(fmtflags):取消格式标志。unsetf(fmtflags, mask):清除原有格式标志,设置新的格式标志。
流对象的格式化标志如下,它们都在命名空间std::ios中定义:
boolalpha:将布尔值转换为字符串 “true” 或 “false”。dec:将输入或输出的数字转换为十进制。hex:将输入或输出的数字转换为十六进制。oct:将输入或输出的数字转换为八进制。showbase:在输出数字时,显示数字的进制前缀符。uppercase:在输出数字时,数字中的字母转换为大写。showpos:在输出数字时,显示’+'号。fixed:将输入或输出的数字转换为固定精度(小数位数固定)形式。scientific:将输入或输出的数字转换为科学计数法。showpoint:在输出整数浮点数时,显示小数点。skipws:忽略输入中的空格。默认开启unitbuf:在每次输出时,刷新缓冲区。cerr 默认开启。left:将输出的字符串左对齐。right:将输出的字符串右对齐。internal:只对有符号的数字有效。符号左对齐,数值右对齐。adjustfield:重置对齐格式标志:left、right、internal。basefield:重置数字的进制格式标志:dec、hex、oct。floatfield:重置浮点数的格式标志:fixed、scientific。
注意:
setf、unsetf函数的参数可以组合使用。- 使用
setf设置的标志, 可能会发生冲突,产生意想不到的输出。在设置冲突的标志前,请先使用unsetf取消冲突的标志。 - 宽度设置只会生效一次。只对最近的一个输出有效。
- 其他格式设置后,一直生效,直到手动关闭。
1.2 流操作符
流操作符必须与流运算符<< 和 >>一起使用才有效果。
流操作符均已包含在标准库<iostream>中。使用流操作符无需<iomanip>库。
1.2.1 输出流操作符
- 布尔值表示
boolalpha: 显示为 true/false。noboolalpha: 显示为 1/0。
- 文本对齐
left: 左对齐。right:右对齐。(默认)internal:符号对齐。符号左对齐,数值右对齐。
- 数值表示
dec:十进制。(默认)hex:十六进制。oct:八进制。showbase:显示进制前缀符。showpos:显示正数符号。uppercase:16进制字母大写。noshowbase: 不显示进制前缀符。(默认)noshowpos:不显示正数符号。(默认)nouppercase: 16进制字母小写。(默认)
- 浮点数表示:默认情况下最多显示6位有效数字,并自动选择最简短的小数表示方式(科学计数法或浮动精度)。
showpoint:显示小数点。noshowpoint:不显示小数点。为整数时不显示。(默认)fixed:使用固定精度。默认为6位小数。精度不够自动补0。scientific:使用科学计数法。默认为6位小数。精度不够自动补0。hexfloat:使用十六进制表示。
- 其他
unitbuf:每次 << 后刷新缓冲区。std::cerr 默认开启。
1.2.2 输入流操作符
<iostream>- 布尔值输入
boolalpha: 可输入 true/false。noboolalpha: 可输入 1/0。
- 整型输入
dec:输入十进制数。(默认)hex:输入十六进制数。可带前缀,可为负数。oct:输入八进制输。可为负数。
- 浮点数输入
- 无需任何格式化
- 可输入整数、小数、科学计数法小数。
- 其他
skipws:跳过空白字符。默认开启。
- 布尔值输入
注意:
- 流操作符基本与格式化标志一致,但没有
adjustfield、basefield、floatfield。 - 流操作符是对格式化标志的封装和对流运算符
<<和>>的重载。与格式化标志不是一个东西。
1.3 全局函数
C++的流对象输入输出格式也可以通过标准库中定义的全局函数来实现。
这些全局函数返回流操作符,必须与流运算符<< 和 >>一起使用才有效果。
以下全局函数定义在命名空间std中:
setprecision(int n):设置精度为 n 位。只对浮点数有效。setw(int n):设置宽度为 n 个字符。缓冲刷新后失效。setfill(char c):设置填充字符为 c。setiosflags(fmtflags):设置格式。可以使用位运算符进行组合,一次设置多个。fmtflags为格式化标志,与流对象成员函数使用同一套格式化标志。resetiosflags(fmtflags):取消格式。可以使用位运算符进行组合。一次设置多个
注意:
- 这些全局函数的返回值必须通过流运算符
<<和>>作用在流对象上。单独使用是没有效果的。 - fmtflags为格式化标志,与流对象成员函数使用同一套格式化标志。
- 精度、宽度和填充字符函数也必须与流运算符一起使用才有效果。
二、格式化输入输出演示
下面分别使用iostream库和iomanip库中的格式化内容演示四种内容的格式化输入输出方案。
- 布尔值
- 整数
- 浮点数
- 字符串
2.1 使用iostream库
通过iostream库中的流操作符以及流对象的成员函数便足以独立完成所有的格式化内容了。
2.1.1 布尔值输入输出
布尔值输出演示:
#include <iostream>
using namespace std;
int main()
{
// 布尔值格式化输出
bool b = true;
cout << b << endl; // 1 默认输出
cout << boolalpha << b << endl; // true 使用布尔值单词输出
cout << noboolalpha << b << endl; // 1 关闭布尔值单词输出
cout.setf(ios::boolalpha);
cout << b << endl; // true
cout.unsetf(ios::boolalpha);
cout << b << endl; // 1
return 0;
}
布尔值输入演示:
注意
- 布尔值数字输入,只读取一个字节,非
0的输入都是true,只有0才是false。 - 布尔值字符串输入,只能输入
true和false。否则会发生错误,影响后续输入。 cin.clear()可清空输入缓存区,避免错误输入影响后续输入。
#include <iostream>
using namespace std;
int main()
{
// 布尔值格式化输入
bool b1;
cout << "请输入一个布尔值(0/1):";
cin >> b1;
cin.clear(); // 清空输入缓冲区
cout << boolalpha << b1 << endl;
cout << "请输入一个布尔值(false/true):";
cin >> boolalpha >> b1;
cout << b1 << endl;
cout << "请输入一个布尔值(false/true):";
cin >> b1;
cout << b1 << endl;
cout << "请输入一个布尔值(0/1):";
cin >> noboolalpha >> b1;
cout << b1 << endl;
cout << "请输入一个布尔值(0/1):";
cin >> b1;
cout << b1 << endl;
return 0;
}
2.1.2 整数输入输出
整数的格式化输入输出主要演示整数的符号、进制表示。
注意:
- 负数的16进制输出为其内存表示。
- 负数不能输出为8进制、16进制对应的数值。
整数输出演示:
#include <iostream>
using namespace std;
int main()
{
// 进制
int num = 64;
cout << "(1) 进制表示法:" << endl;
cout << "十进制:" << num << endl;
cout << "十六进制:" << hex << num << endl;
cout << "八进制:" << oct << num << endl;
// 显示进制前缀
cout << "(2) 进制前缀显示:" << endl;
cout << showbase;
cout << "十进制:" << dec << num << endl;
cout << "十六进制:" << hex << num << endl;
cout << "八进制:" << oct << num << endl;
// 16进制字母大写
cout << "(3) 十六进制字母大写显示:" << endl;
cout << uppercase;
cout << "十六进制:" << hex << 0xfa8 << endl;
// 显示符号,只有十进制可以
cout << "(4) 数值(十进制)符号显示:" << endl;
cout << dec << showpos;
cout << "正数:" << num << endl;
cout << "负数:" << -num << endl;
// 关闭符号显示
cout << "(5) 数值(十进制)符号关闭:" << endl;
cout << noshowpos;
cout << "正数:" << num << endl;
// 关闭进制前缀显示
cout << "(6) 进制前缀关闭:" << endl;
cout << noshowbase;
cout << hex << num << endl;
// 关闭十六进制字母大写
cout << "(7) 十六进制字母大写关闭:" << endl;
cout << nouppercase;
cout << hex << 0xfa8 << endl;
return 0;
}
整数输入演示:
注意
- 输入流对象可以接收16进制、8进制的负数,转换为实际值。
- 输入16进制数值可以带前缀,也可以不带前缀。
#include <iostream>
using namespace std;
int main()
{
// 整数格式化输入
cout << dec;
cout << "请输入一个十进制整数:";
cin >> dec >> num;
cout << "输入的十进制整数为:" << num << endl;
cout << "请输入一个十六进制整数:";
cin >> hex >> num; // 允许带前缀、允许输入负数
cout << "输入的十六进制整数为:" << num << endl;
cout << "请输入一个八进制整数:";
cin >> oct >> num; // 允许带前缀、允许输入负数
cout << "输入的八进制整数为:" << num << endl;
return 0;
}
2.1.3 浮点数输入输出
浮点数输出演示:
注意:
- 浮点数为整时,默认不显示小数点以及小数点后面的0。
- 默认情况下会自动根据输出的长度来决定是否使用科学计数法输出。
- 浮点数精度默认为最多6个有效数字。可由成员函数
precision(n)修改有效数字个数。 - 格式化标志
fixed和scientific默认都是保留6位小数,可由成员函数precision(n)修改小数位数。
#include <iostream>
using namespace std;
int main()
{
// 浮点数格式化输出
// 小数点显示
cout << "小数点显示:" << endl;
float f = 12.00;
cout << "默认情况:" << f << endl;
cout << "显示小数点:" << showpoint << f << endl;
cout << "不显示小数点:" << noshowpoint << f << endl;
// 16进制浮点数
cout << "16进制浮点数:" << hexfloat << 45.25 << endl;
cout.unsetf(ios::floatfield); // 恢复默认
// 浮点数输出格式
cout << "浮点数输出格式:" << endl;
float pi = 3.1415926535897932384626433832795f;
cout << "默认情况:" << endl;
cout << "pi = " << pi << endl;
cout << "10pi = " << 10 * pi << endl;
cout << "pi/100000 = " << pi/100000 << endl;
cout << "固定精度:" << endl;
cout << fixed;
cout << "pi = " << pi << endl;
cout << "10pi = " << 10 * pi << endl;
cout << "pi/100000 = " << pi/100000 << endl;
cout << "科学计数法:" << endl;
cout << scientific;
cout << "pi = " << scientific << pi << endl;
cout << "10pi = " << 10 * pi << endl;
cout << "pi/100000 = " << pi/100000 << endl;
cout.unsetf(ios::floatfield);
cout << "精度设置:" << endl;
cout << "浮动精度(有效数个数)" << endl;
cout.precision(2);
cout << "pi = " << pi << endl;
cout << "固定精度(小数位数)" << endl;
cout << "pi = " << fixed << pi << endl;
return 0;
}
浮点数输入演示:
注意
- 浮点数输入,只能是十进制的,既可以是常规小数形式,也可以是科学计数法。它会自己判断用户的输入格式,并转换成小数存储。
- 无需设置相关标志。
hexfloat16进制浮点数标志对输入流没用。
#include <iostream>
using namespace std;
int main()
{
// 浮点数格式化输入
// 默认输入(整数、小数、科学计数法均可)
cout << showpoint;
cout << "默认输入:" << endl;
cout << "请输入一个浮点数:";
cin >> pi;
cout << "pi = " << pi << endl;
cout << "请输入一个浮点数(科学计数法):";
cin >> pi;
cout << "pi = " << pi << endl;
// 不支持16进制浮点数输入
cout << "请输入一个浮点数(16进制):";
cin >> hexfloat >> pi; // 无效
cout << "pi = " << pi << endl;
cout << hexfloat << pi << endl;
return 0;
}
2.1.4 字符串输入输出
字符串输出演示:
注意
- width()宽度设置成员函数只对下一项输出字符串有效,即下一个
<<操作的字符串。之后便会失效,需要重新设置。
#include <iostream>
using namespace std;
int main()
{
// 格式化输出文本对齐
cout.width(20); // 只对下一项输出有效
cout << "Hello World!" << endl; // 默认对齐
cout.width(20);
cout << left << "Hello World!" << '|' << endl; // 左对齐
cout.width(20);
cout << right << "Hello World!" << '|' << endl; // 右对齐
cout.width(20);
cout << internal << "Hello World!" << '|' << endl; // 符号对齐
cout.width(20);
cout << internal << -897 << '|' << endl; // 符号对齐
cout.width(10);
cout << internal << -89076 << '|' << endl; // 符号对齐
cout.fill('*'); // 设置填充字符
cout.width(20);
cout << internal << -345 << '|' << endl;
return 0;
}
字符串输入演示:
注意
- 字符串输入默认会跳过空白。
- 字符串输入没有格式化。
#include <iostream>
using namespace std;
int main()
{
// 格式化输入文本对齐
// 文本对齐流操作符对输入无效
// 默认跳过前置空白输入,遇到空格结束。
string str;
cout << "请输入左对齐字符串:";
// cin.width(20);
// cin >> left >> str;
cin >> str;
cout << "输入的字符串为:" << str << endl;
//
cout << "请输入右对齐字符串:";
// cin.width(20);
// cin >> right >> str;
cin >> str;
cout << "输入的字符串为:" << str << endl;
// 不能识别符号对齐的输入,比如:+ 989
// 默认可以识别符号与数值紧挨着的数据:+35 -67
cout << "请输入带空格字符串:";
cin.width(20);
cin >> internal >> str;
cout << "输入的字符串为:" << str << endl;
cout << "请输入一个带符号的数:";
int num;
cout << "输入的符号为:" << str << endl;
cin.width(20);
cin >> num;
cout << "输入的数为:" << num << endl;
return 0;
}
2.2 使用iomanip库
2.2.1 布尔值输入输出
布尔值输出演示:
#include <iostream>
using namespace std;
int main()
{
// 布尔值格式化输出
bool b = true;
cout << b << endl; // 1 默认输出
cout << setiosflags(ios::boolalpha) << b << endl; // true 使用布尔值单词输出
cout << resetiosflags(ios::boolalpha) << b << endl; // 1 关闭布尔值单词输出
return 0;
}
布尔值输入演示:
注意
- 布尔值数字输入,只读取一个字节,非
0的输入都是true,只有0才是false。 - 布尔值字符串输入,只能输入
true和false。否则会发生错误,影响后续输入。 cin.clear()可清空输入缓存区,避免错误输入影响后续输入。
#include <iostream>
using namespace std;
int main()
{
// 布尔值格式化输入
bool b1;
cout << "请输入一个布尔值(0/1):";
cin >> b1;
cin.clear(); // 清空输入缓冲区
cout << boolalpha << b1 << endl;
cout << "请输入一个布尔值(false/true):";
cin >> setiosflags(ios::boolalpha) >> b1;
cout << b1 << endl;
cout << "请输入一个布尔值(false/true):";
cin >> b1;
cout << b1 << endl;
cout << "请输入一个布尔值(0/1):";
cin >> resetiosflags(ios::boolalpha) >> b1;
cout << b1 << endl;
cout << "请输入一个布尔值(0/1):";
cin >> b1;
cout << b1 << endl;
return 0;
}
2.2.2 整数输入输出
整数的格式化输入输出主要演示整数的符号、进制表示。
注意:
- 负数的16进制输出为其内存表示。
- 负数不能输出为8进制、16进制对应的数值。
整数输出演示:
#include <iostream>
using namespace std;
int main()
{
// 进制
int num = 64;
cout << "(1) 进制表示法:" << endl;
cout << "十进制:" << num << endl;
cout << "十六进制:" << setiosflags(ios::hex) << num << endl;
cout << "八进制:" << setiosflags(ios::oct)<< num << endl;
// 显示进制前缀
cout << "(2) 进制前缀显示:" << endl;
cout << setiosflags(ios::showbase);
cout << "十进制:" << setiosflags(ios::dec) << num << endl;
cout << "十六进制:" << setiosflags(ios::hex) << num << endl;
cout << "八进制:" << setiosflags(ios::oct) << num << endl;
// 16进制字母大写
cout << "(3) 十六进制字母大写显示:" << endl;
cout << setiosflags(ios::uppercase);
cout << "十六进制:" << hex << 0xfa8 << endl;
// 显示符号,只有十进制可以
cout << "(4) 数值(十进制)符号显示:" << endl;
cout << setiosflags(ios::dec | ios::uppercase);
cout << "正数:" << num << endl;
cout << "负数:" << -num << endl;
// 关闭符号显示
cout << "(5) 数值(十进制)符号关闭:" << endl;
cout << noshowpos;
cout << "正数:" << num << endl;
// 关闭进制前缀显示
cout << "(6) 进制前缀关闭:" << endl;
cout << setiosflags(ios::noshowbase);
cout << hex << num << endl;
// 关闭十六进制字母大写
cout << "(7) 十六进制字母大写关闭:" << endl;
cout << setiosflags(ios::nouppercase);
cout << hex << 0xfa8 << endl;
return 0;
}
整数输入演示:
C++ 进制操作符可以允许用户输入16进制和8进制的数值。
注意
- 输入流对象可以接收16进制、8进制的负数,转换为实际值。
- 输入16进制数值可以带前缀,也可以不带前缀。
#include <iostream>
using namespace std;
int main()
{
// 整数格式化输入
cout << setiosflags(ios::dec);
cout << "请输入一个十进制整数:";
cin >> setiosflags(ios::dec) >> num;
cout << "输入的十进制整数为:" << num << endl;
cout << "请输入一个十六进制整数:";
cin >> setiosflags(ios::dec) >> num; // 允许带前缀、允许输入负数
cout << "输入的十六进制整数为:" << num << endl;
cout << "请输入一个八进制整数:";
cin >> setiosflags(ios::oct) >> num; // 允许带前缀、允许输入负数
cout << "输入的八进制整数为:" << num << endl;
return 0;
}
2.2.3 浮点数输入输出
浮点数输出演示:
注意:
- 浮点数为整时,默认不显示小数点以及小数点后面的0。
- 默认情况下会自动根据输出的长度来决定是否使用科学计数法输出。
- 浮点数精度默认为最多6个有效数字。可由成员函数
setprecision(n)修改有效数字个数。- 格式化标志
fixed和scientific默认都是保留6位小数,可由成员函数setprecision(n)修改小数位数。
#include <iostream>
using namespace std;
int main()
{
// 浮点数格式化输出
// 小数点显示
cout << "小数点显示:" << endl;
float f = 12.00;
cout << "默认情况:" << f << endl;
cout << "显示小数点:" << setiosflags(ios::showpoint) << f << endl;
cout << "不显示小数点:" << resetiosflags(ios::showpoint) << f << endl;
// 16进制浮点数
cout << "16进制浮点数:" << hexfloat << 45.25 << endl;
cout << resetiosflags(ios::floatfield); // 恢复默认
// 浮点数输出格式
cout << "浮点数输出格式:" << endl;
float pi = 3.1415926535897932384626433832795f;
cout << "默认情况:" << endl;
cout << "pi = " << pi << endl;
cout << "10pi = " << 10 * pi << endl;
cout << "pi/100000 = " << pi/100000 << endl;
cout << "固定精度:" << endl;
cout << setiosflags(ios::fixed);
cout << "pi = " << pi << endl;
cout << "10pi = " << 10 * pi << endl;
cout << "pi/100000 = " << pi/100000 << endl;
cout << "科学计数法:" << endl;
cout << setiosflags(ios::scientific);
cout << "pi = " << scientific << pi << endl;
cout << "10pi = " << 10 * pi << endl;
cout << "pi/100000 = " << pi/100000 << endl;
cout << resetiosflags(ios::floatfield);
cout << "精度设置:" << endl;
cout << "浮动精度(有效数个数)" << endl;
cout << setprecision(2);
cout << "pi = " << pi << endl;
cout << "固定精度(小数位数)" << endl;
cout << "pi = " << fixed << pi << endl;
return 0;
}
浮点数输入演示:
注意
- 浮点数输入,只能是十进制的,既可以是常规小数形式,也可以是科学计数法。它会自己判断用户的输入格式,并转换成小数存储。
- 无需设置相关标志。
hexfloat16进制浮点数标志对输入流没用。
#include <iostream>
using namespace std;
int main()
{
// 浮点数格式化输入
// 默认输入(整数、小数、科学计数法均可)
cout << showpoint;
cout << "默认输入:" << endl;
cout << "请输入一个浮点数:";
cin >> pi;
cout << "pi = " << pi << endl;
cout << "请输入一个浮点数(科学计数法):";
cin >> pi;
cout << "pi = " << pi << endl;
return 0;
}
2.2.4 字符串输入输出
字符串输出演示:
注意
- width()宽度设置成员函数只对下一项输出字符串有效,即下一个
<<操作的字符串。之后便会失效,需要重新设置。
#include <iostream>
using namespace std;
int main()
{
// 格式化输出文本对齐
cout << "Hello World!" << endl; // 默认对齐
cout << setw(20) << setiosflags(ios::left) << "Hello World!" << '|' << endl; // 左对齐
cout << setw(20) << setiosflags(ios::right)<< "Hello World!" << '|' << endl; // 右对齐
cout << setw(20) << setiosflags(ios::internal )<< "Hello World!" << '|' << endl; // 符号对齐
cout << setw(20) << setiosflags(ios::internal )<< -897 << '|' << endl; // 符号对齐
cout << setw(20) << setiosflags(ios::internal )<< -89076 << '|' << endl; // 符号对齐
cout << setfill('*'); // 设置填充字符
cout << setw(20) << setiosflags(ios::internal )<< -345 << '|' << endl;
return 0;
}
字符串输入演示:
注意
- 字符串输入默认会跳过空白。
- 字符串输入没有格式化。
#include <iostream>
using namespace std;
int main()
{
// 格式化输入文本对齐
// 文本对齐流操作符对输入无效
// 默认跳过前置空白输入,遇到空格结束。
string str;
cout << "请输入左对齐字符串:";
// cin >> setw(20) >> setiosflags(ios::left) >> str;
cin >> str;
cout << "输入的字符串为:" << str << endl;
cout << "请输入右对齐字符串:";
// cin >> setw(20) >> setiosflags(ios::right )>> str;
cin >> str;
cout << "输入的字符串为:" << str << endl;
// 不能识别符号对齐的输入,比如:+ 989
// 默认可以识别符号与数值紧挨着的数据:+35 -67
cout << "请输入带空格字符串:";
cin >> setw(20) >> setiosflags(ios::internal) >> str;
cout << "输入的字符串为:" << str << endl;
cout << "请输入一个带符号的数:";
int num;
cout << "输入的符号为:" << str << endl;
cin >> num;
cout << "输入的数为:" << num << endl;
return 0;
}
584

被折叠的 条评论
为什么被折叠?



