输入输出流
1.io对象要求能转换成bool类型。对处于正常状态的io对象转成true,对处于错误状态的io对象转成false
2.处于错误状态的io对象拒绝执行io操作,.clear()清除错误状态( 不是清楚缓冲区)清除输入缓冲区用.ignore(字符数,‘结束字符’);
这两个版本都可以用第三个参数指定到用什么字符为止,默认是'\n'
例子:
#include<iostream>
#include<string>
using namespace std;
int main()
{
cout<<"cin="<<cin<<endl; //输出cin和cout对象的地址
cout<<"cout="<<cout<<endl;
int n;
cin>>n;
cout<<"cin="<<cin<<endl; //如果输入的不是整数的话,cin处于错误状态,输入cin为0
if(cin){cout<<"平安无事"<<endl;}
if(!cin)
{
cout<<"出事了"<<endl;
cin.clear();
} //cin处于错状态 cin对象转为false,当cin处于错误状态是 cin拒绝执行io操作
//输入str则为空,要想使cin正常执行io操作,则要将cin的错误信息清空 cin.clear();
string str;
cin>>str;
cout<<"str=["<<str<<"]"<<end;
}
2)getline
i对象.getline(char数组,数组大小); 数组不够大,不能读完一整行,cin会设置错误状态
getline(i对象,string对象引用); 全局函数,不是成员函数
例子:
#include<iostream>
#include<string>
using namespace std;
int main()
{
char buf[10];
if(!cin.getline(buf,sizoef(buf))) //如果输入的字符大于10个,cin不能得到完整的一行,则cin处于错误状态
{
cout<<"行超长!"<<endl;
cin.clear(); //清除错误状态
cin.ignore(1000,‘\n’); //清除缓冲区
}
string str;
getline(cin,str);
cout<<"buf=["<<buf<<"]"<<endl;
cout<<"str=["<<str<<"]"<<endl;
}
3)i.putback(字符);
i.peek(); 查看输入缓冲区中的第一个字符
cin>>ws; 跳过空白字符
例子:
#include<iostream>
#include<stroing>
using namespace std;
int main()
{
char c;
cin>>ws; //跳过空白字符
cin=get(c);
cin.putback(c); //退回输入的字符
if(isdigit(c))
{
double d;
cin>>d;
cout<<"d="<<d<<endl;
}
else
{
string str;
cin>>str;
cout<<"str="<<str<<endl;
}
cin>>ws;
if(cin.peek()>='0'&&cin.peek()<='9')
{
double d;
cin>>d;
cout<<"d="<<d<<endl;
}
else
{
string str;
cin>>str;
cout<<"str="<<str<<endl;
}
}
sstream 字符串输入流
istringstream 从字符串中输入
例子:
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{
string s="1234 6.5 x hello 234 100";
istringstream is(s);
int a,b,c;
double d;
char e;
char buf[100];
is>>a>>d>>e>>buf>>oct>>b>>hex>>c;//oct 八进制输入 hex十六进制输入
cout<<"a="<<a<<",b="<<b<<",c="<<c
<<",d="<<d<<",e="<<e<<",buf"<<buf<<endl;
}
ostringstream 输出到字符串中
例子:
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{
string s="1234 6.5 x hello 234 100";
istringstream is(s);
int a,b,c;
double d;
char e;
char buf[100];
is>>a>>d>>e>>buf>>oct>>b>>hex>>c;//oct 八进制输入 hex十六进制输入
cout<<"a="<<a<<",b="<<b<<",c="<<c
<<",d="<<d<<",e="<<e<<",buf"<<buf<<endl;
ostringstream os;
os<<"a="<<a<<",b="<<b<<",c="<<c
<<",d="<<d<<",e="<<e<<",buf"<<buf<<endl;//输出到字符串中
cout<<os.str()<<endl; //os.str() 得到os对象中的字符串
cout<<os.str()[5]<<endl; //读取os对象中的任意一个字符
}
自定义类型:
例子:
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
class Point
{
public:
Point(int x,int y):x(x),y(y){}
friend ostream & operator<<(ostream o,const Point &p)
{
o<<"("<<p.x<<","<<p.y<<")";
return o;
}
private:
int x;
int y;
};
int main()
{
ostringstream os;
Point p(3,5);
os<<"p="<<p<<end;
cout<<os.str()<<endl;
}
文件输入输出流
fstream
ifstream 文件输入流
ofstream 文件输出流
例子:
#include<iostream>
#include<string>
#include<fstream>
int main()
{
string path="1.txt";
ifstream fin(path.c_str()); //文件路径为c风格的字符串
/*
ifstream fin;
fin.open(path.c_str());
同上
*/
ofstream fout("2.txt");
if(!fin) //== if(!fin.is_open())
{
cout<<"打开文件"<<path<<"失败!"<<endl;
return 1;
}
if(!fout)
{
cout<<"打开文件2.txt失败"<<endl;
}
char ch;
while(fin.get(ch)) //fin.get(ch)文件中内容原样输入,fin>>ch 文件中内容不包含空白字符输入
{
cout<<ch;
fout<<ch;
}
fin.clear();// while中fin.get(ch)到发生错误后停止循环 则要fin.clear()清除错误信息
fin.close();
fout.close();
return 0;
}
注意:
while(fin)
{
cout<<ch;
fout<<ch;
}
//会比上代码多出一个字符 多出一个换行符
read wirte 函数
例子:
#include<iostream>
#include<fstream>
using namespace std;
int main(int args,char * argv[])
{
if(args!=3)
{
cout<<args[0]<<" 源文件 新文件"<<endl;
}
ifstream f1(argv[1],ios::binary|ios::in); //打开要读取的文件 ios::binary为二进制读取 ios::in为读取
if(!f1)
{
cout<<argv[1]<<"文件打开失败!"<<end;
return 1;
}
ofstream f2(argv[2],ios::binary|ios::out); //打开写入的文件 ios::binary 写入方式为二进制 ios::out写入
if(!f2)
{
cout<<argv[2]<<"打开文件失败!"<<endl;
return 1;
}
char buf[1000];
while(f1)
{
f1.read(buf,sizeof(buf));
f2.write(buf,f1.gcount()); //不能用sizeof(buf) 因为优肯能读不满 要f1.gcount()获取读取的字节数
}
//f1.close() f2.close() 析构函数会调用自行释放资源
}
注: ios::app 为追加写入
例子2:文件加密写入
#include<iostream>
#include<fstream>
using namespace std;
void encode(char * buf,int bytes)
{
for(int i=0;i<bytes;i++)
++*buf++;
}
int main(int args,char * argv[])
{
if(args!=3)
{
cout<<argv[0]<<" 源文件 新文件"<<endl;
return 0;
}
ifstream f1(argv[1],ios::binary|ios::in);
if(!f1)
{
cout<<argv[1]<<"打开文件失败!"<<endl;
return 1;
}
ofstream f2(argv[2],ios::binary|ios::out);
if(!f2)
{
cout<<argv[2]<<"打开文件失败!"<<endl;
return 1;
}
char buf[100];
while(f1)
{
f1.read(buf,sizeof(buf));
encode(buf,f1.gcount());
f2.write(buf,f1.gcount());
}
}
注:cout可以用write函数 cin也可以用read函数
write 和 read函数的第一个参数都是char *
例子3: 读写加密解密
#include<iostream>
#include<fstream>
using namespace std;
void encode(char * buf,int btyes)
{
for(int i=0;i<btyes;i++)
++*buf++;
}
void decode(char * buf,int btyes)
{
for(int i=0;i<btyes;i++)
--*buf++;
}
int main(int args,char * argv[])
{
if(args!=3)
{
cout<<argv[0]<<" -e|-d 文件"<<endl;
return 0;
}
fstream f1(argv[2],ios::binary|ios::in|ios::out);
if(!f1)
{
cout<<argv[2]<<"文件打开失败!"<<endl;
return 1;
}
char * buf[1000];
int pos1=0,pos2=0;btyes;
bool ok=true;
void (*p)(char * ,int)=argv[1][1]=='e'?encode:decode;
while(ok)
{
f1.seekg(pos1);//f1.seekg(pos1,ios::beg);
f1.read(buf,sizeof(buf));
btyes=f1.gcount();
if(!f1)
{
f1.clear();
ok=false;
}
else
pos2=f1.tellg();
p(buf,btyes);
f1.seekp(pos1);//f1.seekp(-btyes,ios::cur);
f1.write(buf,btyes);
pos1=pos2;
}
}
输入格式:
例子:
#include<iostream>
using namespace std;
int main()
{
cout.width(10); //设置输出的宽度 只对之后的一个输出管用 输出123的宽度为10
cout<<123<<","<<123<<endl;
cout.width(2); //设置输出宽度为2 小于123的宽度 则以123的宽度输出
cout<<123<<","<<123<<endl;
cout<<setw(10)<<123<<","<<hex<<123<<endl;//setw(10)设置输出宽度 带参的控制符需要头文件 iomanip (#include<iomanip>)
//设置宽度只对一个输出有效 但hex十六进制输出则一直有效 后面的输出则全是十六进制 ,要想设会十进制输出则用dec
cout.setf(ios::dec);//oct,hex,showbase(带进制前缀) 设置一下标志(segf())
cout<<showbase<<123<<endl;
cout.unsetf(ios::hex); //取消某个格式
//上为整数进制的
//下小数
cout<<showpoint<<5.0<<endl; //showpoint总是显示小数点,会显示6六位有效数字(输出精度)
cout<<scientific<<95.0<<endl; //输出结果为9.500000e+01 (9.5* 10的一次方)科学计数法输出
cout.precision(3);
cout.unsetf(ios::scientific);
cout<<95.0<<endl; //输出结果:95.0 有效数字的位数为3 在科学计数法中为小数点后有三位
cout<<fixed<<95.0<<endl; 输出结果为 95.000 小数点后三位
cout<<setprecision(2)<<8000.0<<endl; //输出结果:8000.00
//precision() 指定输出的有效数字 如果是科学计数法则为小数点后保留几位,
//如果想输出小数点后保留几位 则用 fixed指定
cout<<showpos<<123<<","<<45.6<<endl;//showpos给正数带正号,给负数带负号
cout<<uppercase<<hex //只管把十六进制的 0x 字母变为大写 科学计数法中的e变为大写
cout<<dec<<setw(10)<<123<<endl;
cout<<setfill('*')<<left<<setw(10)<<123<<endl; //靠左对齐 指定*号来填充空白的
cout<<setfill(' ')<<internal<<setw(10)<<123<<endl; //internal两侧对齐
//unitbuf 不要缓冲 每次输出都要刷新
cout<<unitbuf<<"hello";
cerr<<"world";
}