我们知道,cout是ostream类的预定义对象,在ostream中,重载了操作符<<,且该操作符返回一个ostream引用所以我们可以在一个表达式中连续重复使用该操作符:,今天小编就来说说关于c语言格式化输入的关键字?下面更多详细答案一起来看看吧!
c语言格式化输入的关键字
我们知道,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 << 1234567.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.456789<<endl; // 123.46
cout.width(10); // 设置显示域宽10
cout.fill('*'); // 在显示区域空白处用*填充
cout<<123.456789<<endl; // ****123.46
使用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.456789<<endl;
cout.width(10); // 设置显示域宽10
cout.fill('*'); // 在显示区域空白处用*填充
cout<<resetiosflags(ios::left); // 清除状态左对齐
cout<<setiosflags(ios::right); // 设置右对齐
cout<<123.456789<<endl;
cout<<setiosflags(ios::left|ios::fixed); // 设左对齐,以固定小数位显示
cout.precision(3); // 设置实数显示三位小数
cout<<999.123456<<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.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**
*/
我们可以重载操作符<<,因为该操作符的第一个参数是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;
}
#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/233501?page=2
-End-
,