您的位置:首页 > 编程语言 > C语言/C++

[C++_11] IO_1

2014-03-06 16:22 218 查看

16 IO

16.1 格式化IO

C++提供了两种格式控制的方法:一种方法是使用ios类中有关格式控制的成员函数;另一种方法是使用称为可是控制符的特殊类型的函数

16.1.1 用ios类的成员函数进行格式控制

ios类中有几个成员函数可以用来对输入输出进行格式控制,进行格式控制主要是通过对格式状态字,域宽,填充字符以及输出精度的操作来完成的。

16.1.2 格式状态字

输入输出格式由一个long int类型的格式状态字确定,状态字的各位都控制一定的输入输出特征,例如格式状态子的最右以为为1,则表示在输入时跳过空白字符。在ios类的public部分定义了一个枚举,它的每个成员可以跟别定义格式状态字的每一位。

enum{

skipws =0x0001, //输入时,跳过开头的空白字符(空格,制表,换行)

left =0x0002, //

right =0x0004, //

internal = 0x0008 //数值符号左对齐,数值右对齐

dec,oct,hex //10 8 16进制

showbase //显示“基指示符”如设置hex和showbase,则显示“0x”

showpoint //强制显示float和double型数据的小数点及后的无效0

uppercase //数值中的字母(指数符“e”.16禁制数字)大写显示

showpos //正数前加“+”

scientific fixed //scientific:浮点数科学计数法,fixed:浮点数常规

unitbuf //输出操作后立即刷新所有流,刷新流意味着把输出写到与流相连的设备

stdio //每次输出,刷新stdout和stderr

}

16.1.3 ios类中用于控制输入输出格式的成员函数

long ios::flags(); //返回当前格式状态字

long ios::flags(long); //设置格式状态字并返回

long ios::setf(long); //设置指定的标志位

long ios::unsetf(long); //清除指定的标志位

int ios::width(); //返回当前显示数据的域宽

int ios::width(int); //设置当前显示数据域宽并返回原域宽

char ios::fill(); //返回当前填充字符

char ios::fill(char); //设置填充字符并返回原填充字符

int ios::precision(); //返回当前浮点数的精度

int ios::precision(int); //设置浮点数精度并返回原精度

16.1.4 使用IO操作符进行格式控制

C++预定义的操作符分为带参数的操作符和不带参数的操作符。通常,不带参数的操作符在iostream文件中定义,而带参数的操作符在iomanip文件中定义。

#include<iostream>:

endl //输入时插入换行符并刷新流

ends //输出时在字符串后插入空字符(NULL)最为尾符

flush //刷新,把流从缓冲区输出到目标设备

ws //输入时略去空白字符

dec hex oct //10 16 8进制

#include<iomanip>:

setbase(int n) //设置转换基数为n(0,8,10,16),默认为0,表示10进制输出

resetiosflags(long f) //清除由参数f指定的标志位,用于输入输出

setiosflags(long f) //设置参数f指定的标志位

setfill(char c) //设置填充字符

setprecision(int n) //设置浮点数精度(默认6)

setw(int n) //设置数据宽度

#include<iostream>
#include<iomanip>
#include<string>
#include<typeinfo>

using namespace std;
int main()
{
//成员函数&格式状态字控制
cout << "当前默认状态字:"<< cout.flags() << endl;
cout.flags(ios::skipws|ios::left|ios::hex|ios::showbase|
ios::uppercase|ios::showpos|ios::unitbuf);
cout << "修改后状态字:"<< cout.flags() << dec << "(" << cout.flags()<< ")"<< endl;
cout.fill('#');
cout <<"输出数字65536:" << endl<<setw(8) << 65536 << endl;
cout << "设置填充和域宽:"<< endl;
cout.width(12);  //只对下一句起作用
cout << 65536 << endl <<"注:填充不影响关键字,但保持有效性直到更改"<< endl;
cout << "  关键字一旦修改就不会自动恢复,区别于操作符控制"<< endl;
cout << "****************************" << endl;

//操作符格式控制
cout<< dec << 256 << endl <<  oct << 256 << endl << hex << 256 <<endl;
cout<< setw(15) << setfill('^') << setprecision(8) << 123.456789 << endl;
cout << endl;
return 0;
}
输出结果:



自定义输出格式:

#include<iostream>
using namespace std;

//方法一:无参:类-对象
class HexUpBas
{
public:
friend ostream& operator<<(ostream &o,const HexUpBas hub)
{
return o<< hex << uppercase << showbase ;
}
};

const HexUpBas hub = HexUpBas();

//方法二:有参 类
class wf
{
int w;
unsigned char fill;
public:
wf(int w, unsigned char f=' '):w(w),fill(f){}
friend ostream& operator<<(ostream& o,const wf& x) //临时对象
{
o.width(x.w);
o.fill(x.fill);
return o;
}
};
//方法三:函数
ostream& func(ostream& o)
{
return o<< dec << showpos;
}
// 工作原理:ostream类中
// ostream& operator<<(ostream& (*f)(ostream& o))
// { return f(*this); }

int main()
{
cout << hub << 12346<<endl;
cout << wf(10,'*') <<"hello"<< endl;
cout << func<< 589 << endl;
return 0;
}

16.2 控制台的输入输出

16.2.1格式化的输入输出

cout<< cin>>跳过空白字符,格式自动转换完成的,重载的<< >>来实现的

cerr 无缓冲,也不允许重定向

cout可缓冲,可重定向

clog理论上可缓冲,不可重定向,实际上无缓冲不可重定向

//输出缓冲区遇到换行、有输入、满、程序结束、flush会刷新

cout<<"hello";

cerr<<"world";

clog<<"tarena";

输出结果是cerr东西先出来,然后是clog,最后是cout

如果重定向的话a.out>file cat file结果只有cout的东西重定向了

16.2.2 非格式化的输入输出

.get()读取一个字符,类似C中getchar(),不会跳过空白字符

.put()写一个字符 //ostream& put( char ch );

.getline(char数组,数组大小) //如果不能读完一整行会设置错误状态

getline(i对象,string对象引用) //不是成员函数而是全局函数

这两个版本都可以添加第三个参数,指定结束字符,默认是读到换行,为读到什么字符为止

.ignore() //istream& ignore( int nCount = 1, int delim = EOF );

.putback()

.peek()查看输入缓冲区第一个字符

io对象要求能转换成bool类型,对处于正常状态的io对象转成true,对处于错误状态的io对象转成false

io对象如果正常就是真,错误为假,io对象如果处于错误状态就拒绝io,纠正办
4000
法是cin.clear()(清除错误状态,不清缓冲区)

string s;

s.c_str(); //转成C风格字符串

printf("%s\n",s.c_str());

#include<iostream>
using namespace std;

int main()
{
int i;
cout << "请输入一个数字:"<< endl;
cin >> i;
while(!cin)
{
cout << "输入错误字符!" << endl;
cin.clear();
cin.ignore(200,'\n');//cin.clear()重置了cin的状态,没有清空缓存
cin >> i;  //cin.get()不会改变cin的状态,无论成功与否cin都是true
}
cout << "输入缓冲区中第一个字符:" << cin.peek() << endl;  //查看缓冲区第一个字符(根据上面:回车)
cin.ignore(200,'\n');
cout << "cin.get()可以读取回车,制表,空格,区别于cin >> "<< endl;
cin.get();   //读取一个字符,可以当做程序停顿使用,并不忽略回车,制表,空格
cout <<"停顿完成!" << endl;
cout << "输入字符串以'*'结尾:" << endl;
char str[100];
cin.getline(str,100,'*');//最后一个参数为读到此字符为止,默认为'\n'
cout <<"查看字符串内容:" <<  str << endl;
char c;
cout <<"输入缓冲区中第一个字符:" << cin.peek() << endl;
c=cin.get();
cout<<"读取之后,输入缓冲区中第一个字符:" << cin.peek()<< endl;
cin.putback(c);
cout << "还回之后,输入缓冲区中第一个字符:" <<cin.peek()<<endl;

return 0;
}


输出结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  IO 格式化