c++ 学习笔记 c++ io

输入输出流


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"; 
}

你可能感兴趣的:(C++,IO,自学笔记)