C++|输入输出的格式化控制、重载输出操作符、自定义控制格式符

C++|输入输出的格式化控制、重载输出操作符、自定义控制格式符我们知道 cout 是 ostream 类的预定义对象 在 ostream 中 重载了操作符 lt lt 且该操作符返回一个 ostream 引用

大家好,欢迎来到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

(0)
上一篇 2024-12-25 08:00
下一篇 2024-12-25 08:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信