大家好,欢迎来到IT知识分享网。
我们知道,cout是ostream类的预定义对象,在ostream中,重载了操作符<<,且该操作符返回一个ostream引用。所以我们可以在一个表达式中连续重复使用该操作符:
cout<<""<<12<<endl;
C++使用C中的printf()和scanf()函数进行格式化控制的同时又提供了两种格式化控制的方法: 一种是使用ios类中的有关格式控制的成员函数, 另一种是使用被称为格式控制符的特殊类型的函数。
1 有关格式控制的成员函数
一般来说,ios 类的成员函数进行格式控制主要是通过对格式状态字、域宽、填充字符和输出精度操作来完成的。
1.1 操作状态字的函数
std::cout.setf(std::ios::showpos); // turn on the std::ios::showpos flag std::cout << 27 << '\n'; std::cout.setf(std::ios::showpos | std::ios::uppercase); // turn on the std::ios::showpos and std::ios::uppercase flag std::cout << .89f << '\n'; std::cout.setf(std::ios::showpos); // turn on the std::ios::showpos flag std::cout << 27 << '\n'; std::cout.unsetf(std::ios::showpos); // turn off the std::ios::showpos flag std::cout << 28 << '\n'; std::cout.setf(std::ios::hex); // try to turn on hex output std::cout << 27 << '\n'; std::cout.unsetf(std::ios::dec); // turn off decimal output std::cout.setf(std::ios::hex); // turn on hexadecimal output std::cout << 27 << '\n'; // Turn on std::ios::hex as the only std::ios::basefield flag std::cout.setf(std::ios::hex, std::ios::basefield); std::cout << 27 << '\n'; /*output: +27 +1.23457E+006 +27 28 27 1B 1B
cout.setf()使用的标志,其是一个enum类型:
boolalpha |
enum值 |
remark |
skipws |
0x0001 |
当从一个流进行读取时,跳过空白字符(spaces, tabs, newlines) |
left |
0x0002 |
输出调整为左对齐. |
right |
0x0004 |
输出调整为右对齐. |
internal |
0x0008 |
将填充字符回到符号和数值之间. |
dec |
0x0010 |
用十进制格式显示数值. |
oct |
0x0020 |
用八进制格式显示数值. |
hex |
0x0040 |
用十六进制格式显示数值. |
showbase |
0x0080 |
输出时显示所有数值的基数. |
showpoint |
0x0100 |
显示小数点和额外的零,即使不需要. |
uppercase |
0x0200 |
以大写的形式显示科学记数法中的”e”和十六进制格式的”x”. |
showpos |
0x0400 |
在非负数值前面显示”+(正号)”. |
scientific |
0x0800 |
用科学记数法显示浮点数. |
fixed |
0x1000 |
用正常的记数方法显示浮点数(与科学计数法相对应). |
unitbuf |
0x2000 |
在每次插入以后,清空缓冲区. |
1.2 控制域宽、填充字符和输出精度的成员函数
cout.precision(5); // 设置除小数点外有五位有效数字 cout<<123.<<endl; // 123.46 cout.width(10); // 设置显示域宽10 cout.fill('*'); // 在显示区域空白处用*填充 cout<<123.<<endl; // 123.46
2 格式控制符
使用ios 类的成员函数控制输入输出格式时,每个函数的调用都要写一条语句, 它们还不能直接嵌入到输入/输出语句中, 使用很不方便。为此, C++提供了另外一种输入/输出格式的控制方法, 即使用一种称为格式控制符的特殊函数。
预定义格式控制符分为带参数和不带参数的两种, 带参数的在头文件iomanip.h中定义,不带参数的在头文件iostream.h中定义。在使用它们时, 程序中应包含相应的头文件。格式控制符被嵌入到输入/输出语句中控制输入/输出的格式, 而不是执行输入/输出操作。
#include <iostream> #include <iomanip> using namespace std; int main() { cout<<setiosflags(ios::left|ios::showpoint); // 设左对齐,以一般实数方式显示 cout.precision(5); // 设置除小数点外有五位有效数字 cout<<123.<<endl; cout.width(10); // 设置显示域宽10 cout.fill('*'); // 在显示区域空白处用*填充 cout<<resetiosflags(ios::left); // 清除状态左对齐 cout<<setiosflags(ios::right); // 设置右对齐 cout<<123.<<endl; cout<<setiosflags(ios::left|ios::fixed); // 设左对齐,以固定小数位显示 cout.precision(3); // 设置实数显示三位小数 cout<<999.<<endl; cout<<resetiosflags(ios::left|ios::fixed); //清除状态左对齐和定点格式 cout<<setiosflags(ios::left|ios::scientific); //设置左对齐,以科学技术法显示 cout.precision(3); //设置保留三位小数 cout<<123.45678<<endl; return 0; } /* 123.46 123.46 999.123 1.235e+02 */
其中 cout.setf 跟 setiosflags 一样,cout.precision 跟 setprecision 一样,cout.unsetf 跟 resetiosflags 一样。
setiosflags(ios::fixed) 固定的浮点显示 setiosflags(ios::scientific) 指数表示 setiosflags(ios::left) 左对齐 setiosflags(ios::right) 右对齐 setiosflags(ios::skipws 忽略前导空白 setiosflags(ios::uppercase) 16进制数大写输出 setiosflags(ios::lowercase) 16进制小写输出 setiosflags(ios::showpoint) 强制显示小数点 setiosflags(ios::showpos) 强制显示符号
2.1 iostream 中定义的不带参数的操作符:
操作符 |
描述 |
输入 |
输出 |
boolalpha |
启用boolalpha标志 |
√ |
√ |
dec |
启用dec标志 |
√ |
√ |
endl |
输出换行标示,并清空缓冲区 |
√ |
|
ends |
输出空字符 |
√ |
|
fixed |
启用fixed标志 |
√ |
|
flush |
清空流 |
√ |
|
hex |
启用 hex 标志 |
√ |
√ |
internal |
启用 internal 标志 |
√ |
|
left |
启用 left 标志 |
√ |
|
noboolalpha |
关闭boolalpha 标志 |
√ |
√ |
noshowbase |
关闭showbase 标志 |
√ |
|
noshowpoint |
关闭showpoint 标志 |
√ |
|
noshowpos |
关闭showpos 标志 |
√ |
|
noskipws |
关闭skipws 标志 |
√ |
|
nounitbuf |
关闭unitbuf 标志 |
√ |
|
nouppercase |
关闭uppercase 标志 |
√ |
|
oct |
启用 oct 标志 |
√ |
√ |
right |
启用 right 标志 |
√ |
|
scientific |
启用 scientific 标志 |
√ |
|
showbase |
启用 showbase 标志 |
√ |
|
showpoint |
启用 showpoint 标志 |
√ |
|
showpos |
启用 showpos 标志 |
√ |
|
skipws |
启用 skipws 标志 |
√ |
|
unitbuf |
启用 unitbuf 标志 |
√ |
|
uppercase |
启用 uppercase 标志 |
√ |
|
ws |
跳过所有前导空白字符 |
√ |
2.2 iomanip 中定义的带参数的操作符:
操作符 |
描述 |
输入 |
输出 |
resetiosflags(long f) |
关闭被指定为f的标志 |
√ |
√ |
setbase(int base) |
设置数值的基本数为base |
√ |
|
setfill(int ch) |
设置填充字符为ch |
√ |
|
setiosflags(long f) |
启用指定为f的标志 |
√ |
√ |
setprecision(int p) |
设置数值的精度(四舍五入) |
√ |
|
setw(int w) |
设置域宽度为w |
√ |
3 自定义控制格式符
3.1 自定义不带参控制格式符
#include <iomanip> #include <iostream> using namespace std; ostream &output1(ostream &out) { out.setf(ios::left); out<<setw(10)<<dec<<setfill('*'); return out; } ostream &endLine(ostream &out) { return out<<'\n'<<flush; } void testOutput1() { cout<<345<<endl; cout<<output1<<345<<endLine; getchar(); } int main() { testOutput1(); getchar(); return 0; } /* 345 345* */
关于setw()与width成员:
struct _Setw { int _M_n; }; inline _Setw setw(int __n) { _Setw __x; __x._M_n = __n; return __x; } template<typename _CharT, typename _Traits> inline basic_istream<_CharT,_Traits>& operator>>(basic_istream<_CharT,_Traits>& __is, _Setw __f) { __is.width(__f._M_n); return __is; }
3.2 自定义带参控制格式符
#include <iomanip.h> #include <iostream.h> #include <stdio.h> //using namespace std; ostream &output1(ostream &out,int n) { out.setf(ios::left); out<<setw(n)<<dec<<setfill('*'); return out; } ostream &endLine(ostream &out) { return out<<'\n'<<flush; } OAPP(int) OutPut(output1); void testOutput1() { cout<<345<<endl; cout<<OutPut(5)<<345<<endLine; } int main() { testOutput1(); getchar(); return 0; } /* 345 345 */
4 重载操作符operator<<
我们可以重载操作符<<,因为该操作符的第一个参数是ostream对象,所以一般重载为友元,且返回一个引用:
#include <iostream> using namespace std; class point { int x,y; public: point():x(0),y(0){} point(int a,int b):x(a),y(b){} friend ostream& operator<<(ostream& output,point pt); }; ostream& operator<<(ostream& output,point pt) { output<<"["<<pt.x<<","<<pt.y<<"]"<<endl; return output; } void test() { point pt(10,20); cout<<pt; // [10,20] } int main() { test(); getchar(); return 0; }
5 用模板来定义流的带参控制符
#include <iostream> using namespace std; template<class T> class OMANIP{ typedef ostream& (*func)(ostream&,const T&); T i; func f; public: OMANIP(func ff, T ii):f(ff),i(ii){} friend ostream& operator<<(ostream& os,const OMANIP<T>& m) { return m.f(os,m.i); } }; struct point { int x; int y; point(int xx, int yy) : x(xx) , y(yy) {} point(const point& pp) : x(pp.x), y(pp.y) {} }; ostream& move(ostream& os, const point& p) // 用于类OMANIP成员func ff { os << "move[" << p.x << "," << p.y << "]"; return os; } OMANIP<point> move(int x,int y) // 函数重载 { point pt(x,y); return OMANIP<point>(move,pt); } main() { cout << move(1,2) << "str" << endl; // move返回的对象已重载了operator<<, // 重载的<<是对move(ostream&,const point&)的调用 getchar(); } // move[1,2]str
ref
https://www.runoob.com/cplusplus/cpp-basic-input-output.html
https://www.learncpp.com/cpp-tutorial/output-with-ostream-and-ios/
https://bbs.csdn.net/topics/?page=2
-End-
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/164489.html