9.4 格式化输入和输出
C++语言的I/O流类库提供了多种方法来实现格式化输入和输出。这些方法主要分为两类:使用成员函数设置标志位和格式,以及使用流类库中提供的操作子。本文将详细介绍这两种方法。
9.4.1 使用成员函数设置流的格式化标志位
在 ios
类的公有成员部分定义了一些格式控制常量和成员函数,使用它们可以对数据格式进行转换。
控制格式的标志位
ios
类提供了多种控制格式的标志位,如表9-1所示:
标志位 | 值 | 含义 |
---|---|---|
skipws | 0x0001 | 跳过输入中的空白符 |
left | 0x0002 | 输出数据按输出域左对齐 |
right | 0x0004 | 输出数据按输出域右对齐 |
internal | 0x0008 | 数据符号左对齐,数据本身右对齐,符号和数据之间为填充符 |
dec | 0x0010 | 转换基数为十进制形式 |
oct | 0x0020 | 转换基数为八进制形式 |
hex | 0x0040 | 转换基数为十六进制形式 |
showbase | 0x0080 | 输出的数值数据前面带有基数符号(0或0x) |
showpoint | 0x0100 | 浮点数输出带有小数点 |
uppercase | 0x0200 | 用大写字母输出十六进制数值 |
showpos | 0x0400 | 正数前面带有“+”符号 |
scientific | 0x0800 | 浮点数输出采用科学表示法 |
fixed | 0x1000 | 使用定点数形式表示浮点数 |
unitbuf | 0x2000 | 完成输入操作后立即刷新流的缓冲区 |
stdio | 0x4000 | 完成输入操作后刷新系统的 stdout, stderr |
使用成员函数设置标志字
ios
类中定义了一个 long
型数据成员用于记录当前格式化的状态,即各标志位的设置值。维护该标志字的成员函数包括:
long flags()
:返回标志字。long flags(long)
:使用参数值更新标志字,返回更新前的标志字。long setf(long setbits, long field)
:将field
所指定的标志清零,将setbits
为1的位置1,返回以前的标志字。long setf(long)
:设置参数所指定的标志位,返回更新前的标志字。long unsetf(long)
:清除参数所指定的标志位,返回更新前的标志字。
为了使用方便,ios
类中定义了以下静态类对象:
static const long basefield;
:其值为dec | oct | hex
static const long adjustfield;
:其值为left | right | internal
static const long floatfield;
:其值为scientific | fixed
示例:设置标志字和进行格式化输出
#include <iostream>
using namespace std;
int main() {
cout.setf(ios::oct, ios::basefield);
cout << "OCT: 48 --> " << 48 << endl;
cout.setf(ios::dec, ios::basefield);
cout << "DEC: 48 --> " << 48 << endl;
cout.setf(ios::hex, ios::basefield);
cout << "HEX: 48 --> " << 48 << endl;
cout.setf(ios::showbase);
cout << "HEX: 32 --> " << 32 << endl;
cout.setf(ios::uppercase);
cout << "HEX: 254 --> " << 254 << endl;
return 0;
}
输出结果:
OCT: 48 --> 60
DEC: 48 --> 48
HEX: 48 --> 30
HEX: 32 --> 0x20
HEX: 254 --> 0XFE
9.4.2 格式输出函数
在 ios
类中定义了一些虚成员函数用于格式化输出:
-
设置输出数据所占宽度的函数:
int width()
:返回当前输出数据时的宽度。int width(int)
:设置输出数据时的宽度。
-
填充当前宽度内的填充字符函数:
char fill()
:返回当前使用的填充字符。char fill(char)
:设置填充字符为参数值所表示的字符,并返回更新前的填充字符。
-
设置浮点数输出精度函数:
int precision()
:返回当前浮点数的有效数字个数。int precision(int)
:设置浮点数输出时的有效数字个数,并返回更新前的值。
示例:格式输出函数的用法
#include <iostream>
using namespace std;
int main() {
cout << "12345678901234567890\n";
int i = 1234;
cout << i << endl;
cout.width(12);
cout << i << endl;
cout.width(12);
cout.fill('*');
cout.setf(ios::left, ios::adjustfield);
cout << i << endl;
cout.width(12);
cout.setf(ios::right, ios::adjustfield);
cout.precision(5);
double j = 12.3456789;
cout << j << endl;
cout << "width: " << cout.width() << endl;
return 0;
}
输出结果:
12345678901234567890
1234
1234
1234********
12.346
width: 0
9.4.3 操作子
C++语言I/O流类库提供了一些操作子来简化格式控制。操作子是对象,可以直接被插入符或提取符操作。
表9-2列出了流类库所定义的操作子:
操作子名 | 含义 |
---|---|
dec | 数值数据采用十进制表示 |
hex | 数值数据采用十六进制表示 |
oct | 数值数据采用八进制表示 |
setbase(int n) | 设置数制转换基数为n (n为0, 8, 10, 16),0表示使用默认基数 |
ws | 提取空白符 |
ends | 插入空字符 |
flush | 刷新与流相关联的缓冲区 |
resetiosflags(long) | 清除参数所指定的标志位 |
setiosflags(long) | 设置参数所指定的标志位 |
setfill(int) | 设置填充字符 |
setprecision(int) | 设置浮点数输出的有效数字个数 |
setw(int) | 设置输出数据项的域宽 |
示例:操作子的用法
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << "12345678901234567890" << endl;
int i = 1234;
cout << i << endl;
cout << setw(12) << i << endl;
cout << resetiosflags(ios::right) << setiosflags(ios::left) << setfill('*') << setw(12) << i << endl;
cout << resetiosflags(ios::left) << setiosflags(ios::right) << setprecision(5) << setw(12) << 12.3456789 << endl;
cout << "width: " << cout.width() << endl;
return 0;
}
输出结果:
12345678901234567890
1234
1234
1234********
12.346
width: 0
结论
通过使用 ios
类的成员函数和流类库提供的操作子,C++程序员可以灵活地控制输入和输出的格式。这些功能使得数据的显示更加直观和易于阅读,增强了程序的可维护性和可读性。希望本文对C++ I/O流库中的格式化输入和输出有一个全面的理解,并为实际编程提供支持。