正文

C++学习笔记·输入输出(4)(转)2006-07-27 19:59:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/argol/16878.html

分享到:

四、格式化输入输出  C++语言中有两种方法可以控制格式化输入输出:流对象的成员函数和操纵器。  <1> 流对象的成员函数  下表中的格式化标志,可以通过成员函数setf()来设置,也可以用unsetf()来复位,如果需要设置多个标志,可以使用 | 运算符(使用标志时前边加上ios::)。───────┬───────────────────────┬────  格式化标志  │              描           述                 │ 默 认───────┼───────────────────────┼────  boolalpha   │ 以alpha格式进行布尔输入输出                  │  off  showbase    │ 显示8进制或16进制前缀                        │  off  showpoint   │ 显示10进制浮点数末尾的零                     │  off  showpos     │ 正数时显示加号                               │  off  skipws      │ 跳过输入中的空白字符                         │  on  uppercase   │ 十六进制显示大写0X和A~F,科学计数显示大写E  │  off  unitbuf     │ 启用单元缓冲                                 │  off───────┴───────────────────────┴────  除了setf()和unsetf()外,常用的成员函数还有:用于设置浮点值显示精度的precision(),注意显示精度包括整数位和小数位;用于设置输出宽度的width(),注意每次输出都需要重新设定输出宽度;用于设置填充字符的fill(),当前设定会保持直到下一次更改填充字符。  下面的程序给出了上述成员函数的使用示例:// ----- Prog01-04.cpp -------------------------------------------------// 功能:流对象的成员函数使用示例#include <iostream>using namespace std;int main(){    bool b = true;    cout << b << '\n';    // 显示为布尔型    cout.setf(ios::boolalpha);    cout << b << '\n';    double x = 12345.6789, y = 12345;    cout << x << ' ' << y << '\n';    // 设定显示精度    cout.precision(11);    cout << x << ' ' << y << '\n';    // 显示末尾的零    cout.setf(ios::showpoint);    cout << x << ' ' << y << '\n';    // 显示正数的符号    cout.setf(ios::showpos);    cout << x << ' ' << y << '\n';    // 恢复符号和显示精度设定    cout.unsetf(ios::showpos);    cout.precision(6);    // 使用科学计数法    double z = 1234567890.123456;    cout.setf(ios::scientific, ios::floatfield);    cout << z << '\n';    cout.setf(ios::uppercase);    cout << z << '\n';    // 设置输出宽度    cout << '|';    cout.width(10);    cout << "hello" << '|' << '\n';    // 设置填充字符    cout << '|';    cout.fill('#');    cout.width(10);    cout << "hello" << '|' << '\n';    system("pause");    return 0;}// ---------------------------------------------------------------------  有一些格式化选项可以具有一定范围的值,例如:用来确定显示整型数基数的ios:basefield可以被设置成10进制、8进制或16进制,由于这些是位域而不是单个的位,可以用带两个参数形式的setf()来设置。───────────┬────────────────────┬───          域          │           描           述              │默认值───────────┼────────────────────┼───  adjustfied (调整域) │left, right, internal (左、右、内部)    │right  basefield  (基数域) │dec, oct, hex (十进制、八进制、十六进制)│dec  floatfield (浮点域) │fixed, scientfic (定点、科学计数法)     │fixed───────────┴────────────────────┴───  下面的示例程序演示了格式化域的用法:// ----- Prog01-05.cpp -------------------------------------------------// 功能:在不同基数下显示整数(使用setf)#include <iostream>using namespace std;int main(){    int x, y, z;    cout << "请输入三个整数: ";    cin >> x >> y >> z;    cout << x << ',' << y << ',' << z << endl;    // 在不同基数下显示    cout << x << ',';    cout.setf(ios::oct, ios::basefield);    cout << y << ',';    cout.setf(ios::hex, ios::basefield);    cout << z << endl;    // 显示基数前缀    cout.setf(ios::showbase);    cout.setf(ios::dec, ios::basefield);    cout << x << ',';    cout.setf(ios::oct, ios::basefield);    cout << y << ',';    cout.setf(ios::hex, ios::basefield);    cout << z << endl;    system("pause");    return 0;}// ---------------------------------------------------------------------  <2> 操纵器  当标识符endl出现在一个输出流中时,一个换行字符就被插入并且流被刷新,endl是操纵器的一个例子,即为了副效应而插入到流的一个对象。在 <iostream>中被声明的系统预定义的操纵器列于下表,使用操纵器来代替显式调用setf函数,可以使代码更为高效。                        简单的操纵器( <iostream> )──────────┬──────────────┬──────────      操 纵 器      │     等价的 setf() 函数     │      描    述──────────┼──────────────┼────────── [fmt flags Group]  │                            │  boolalpha         │setf(boolalpha)             │显示布尔型  noboolalpha       │unsetf(boolalpha)           │显示非布尔型  showbase          │setf(showbase)              │显示基数前缀  noshowbase        │unsetf(showbase)            │不显示基数前缀  showpoint         │setf(showpoint)             │显示小数点  noshowpoint       │unsetf(showpoint)           │不显示小数点  showpos           │setf(showpos)               │显示正数的符号  noshowpos         │unsetf(showpos)             │不显示正数的符号  skipws            │setf(skipws)                │跳过输入中的空白  noskipws          │unsetf(skipws)              │不跳过输入中的空白  uppercase         │setf(uppercase)             │显示为大写  nouppercase       │unsetf(uppercase)           │显示为小写  unitbuf           │setf(unitbuf)               │单元缓冲  ununitbuf         │unsetf(unitbuf)             │全缓冲──────────┼──────────────┼────────── [adjustfield Group]│                            │  left              │setf(left, adjustfield)     │左对齐  right             │setf(right, adjustfield)    │右对齐  internal          │setf(internal, adjustfield) │内部对齐──────────┼──────────────┼────────── [basefield Group]  │                            │  dec               │setf(dec, basefield)        │十进制  oct               │setf(oct, basefield)        │八进制  hex               │setf(hex, basefield)        │十六进制──────────┼──────────────┼────────── [floatfield Group] │                            │  fixed             │setf(fixed, floatfield)     │定点  scientific        │setf(scientific, floatfield)│科学计数法──────────┼──────────────┼────────── [other]            │                            │  endl              │                            │插入一个换行符并刷新  ends              │                            │插入一个空字符  flush             │                            │强制刷新一个流──────────┴──────────────┴──────────  下面的示例程序与Prog01-05.cpp功能完全相同,但代码更为精简和清晰。// ----- Prog01-06.cpp -------------------------------------------------// 功能:在不同基数下显示整数(使用操纵器)#include <iostream>using namespace std;int main(){    int x, y, z;    cout << "请输入三个整数: ";    cin >> x >> y >> z;    cout << x << ',' << y << ',' << z << endl;    // 在不同基数下显示    cout << dec << x << ','         << oct << y << ','         << hex << z << endl;    // 显示基数前缀    cout << showbase;    cout << dec << x << ','         << oct << y << ','         << hex << z << endl;    system("pause");    return 0;}// ---------------------------------------------------------------------  在 <iomanip> 中声明了一些带有参数的操纵器,现列于下表, 使用的时候要在程序头部加上#include <iomanip>指令。需要注意的是,ios::width域是特殊的,它在每次插入后立即重置为0,因此操纵器setfill()与成员函数fill()一样,设定一次只影响输出序列里紧邻的那个对象的打印格式。                       参数化的操纵器( <iomanip> )──────────┬─────────────────────────      操 纵 器      │                 描        述──────────┼─────────────────────────  setioflags(n)     │ 设置所有 n 所设置的标志  resetioflags(n)   │ 复位所有 n 所设置的标志  setbase(n)        │ 等同于: setf(n, ios::basefield)  setprecision(n)   │ 等同于: precision(n)  setw(n)           │ 等同于: width(n)  setfill(n)        │ 等同于: fill(c)──────────┴─────────────────────────  下面的程序演示了对齐方式与字符填充的显示效果。内部对齐(internal)是比较令人困惑的对齐方式,显示的时候如果宽度较大, 会在数值与前导符号(+ / -)或者基数标志(0 / 0x)之间插入填充符号,以下面的程序为例,输出宽度为10字符,用内部对齐方式输出 -12.345 的结果是:|-   12.345|// ----- Prog01-07.cpp -------------------------------------------------// 功能:对齐方式与字符填充的显示效果示例#include <iostream>#include <iomanip>using namespace std;int main(){    double x = -12.345;    // 对齐方式    cout << '|' << setw(10) << x << '|' << endl;    cout << left         << '|' << setw(10) << x << '|' << endl;    cout << right         << '|' << setw(10) << x << '|' << endl;    cout << internal         << '|' << setw(10) << x << '|' << endl;    // 字符填充    cout << right         << '|' << setw(10) << "hello" << '|' << endl;    cout.fill('#');    cout << '|' << setw(10) << "hello" << '|' << endl;    system("pause");    return 0;}// ---------------------------------------------------------------------  >> 关于风格  格式化输入输出中,操纵器可以使代码更加精简,阅读起来也更为清晰,例如Prog01-04.cpp与Prog01-07.cpp中功能相同的两段代码:    // ====== Prog01-04.cpp代码片段 ======    cout << '|';    cout.width(10);    cout << "hello" << '|' << '\n';    cout << '|';    cout.fill('#');    cout.width(10);    cout << "hello" << '|' << '\n';    // ====== Prog01-07.cpp代码片段 ======    cout << right         << '|' << setw(10) << "hello" << '|' << endl;    cout.fill('#');    cout << '|' << setw(10) << "hello" << '|' << endl;  很明显第一段代码显得冗长,可读性不高, 这是因为语句 cout.width(10);切断了输出流序列,而操纵符setw()则可以像输出对象一样插入到输出流序列中去。但如果用 ...<<setfill('#')<<... 代替 cout.fill('#'); 来设置填充字符, 反倒会显得不是很自然,因为填充字符设置之后会保持下去,插入在输出流中不容易直接看明白它的效果。

阅读(5756) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册