文章目录
第九章输入输出流
一、输入输出流的含义
- 程序的输入是指:从输入文件将数据传给程序
- 程序的输出是指:从程序将数据传送给输出文件
- c语言用函数实现输入与输出,c++通过类对象来实现输入与输出
二、c++的输入输出流
1.含义
- 每一个数据流都存在一个内存缓冲区
- 当cout<<时,先将这些数据插入到输出流,然后送到输出缓冲区中保存,直到缓冲区满了或者遇到endl;就停止,将缓冲区的数据显示出来
- 同理cin>>时会形成输入流。
- 总之,缓冲区的数据就是流。
2.与流类库有关的头文件
- iostream:包含了对输入输出流进行操作所需要的基本信息
- fstream:用于用户管理的文件的I/O操作
- iomanip:使用格式化
3.标准输出流
- 在ostream类中对位移运算符进行了重载。cout<<可以输出不同类型的数据。cout<<"c++"就相当于cout.operator<<(“c++”)
- 三个流对象:cout,cerr,clog
- cout输出的信息可以被重定向到文件中
- cerr是标准错误流对象——向标准错误设备输出错误信息,不能被重定向到文件里去
- clog作用与cerr相同,只不过cerr不经过缓存区
4.流成员函数
- cout,put(‘a’):输出a字符,里面也可以是某个字符的ASCII码的值
- cout,put(71).put(79).put(79).put(68).put(’\n’)——连续输出
- cin.get()——若遇到输入流文件的结束符,则返回EOF代表-1
- cin.get(字符数组,字符个数n,终止字符),cin.getline(字符数组或指针,字符个数n,终止字符)
三、对数据文件的操作
- 文件分为二进制文件和ASCII文件
1.文件的打开与关闭
1.磁盘文件
#include<fstream>
ofstream outfile;
outfile.open('f1.dat',ios::out);
outfile.close();
- 定义形式:文件流对象.open(磁盘文件名,输入输出方式)
- 输出形式的文件只能写,不能读,输入形式的文件只能读,不能写
方式 | 作用 |
---|---|
ios::out | 以输出方式打开文件(默认),同时清空原来的内容 |
ios::in | 以输入方式打开文件 |
ios::app | 以输出方式打开文件,写入的数据添加在末尾 |
ios::ate | 打开一个已有的文件,文件指针指向末尾 |
ios::in|ios::out | 文件可读可写 |
ios::in|ios::binary | 以二进制方式打开一个输入文件 |
ios::out|ios::binary | 以二进制方式打开一个输出文件 |
#include <fstream>
using namespace std;
void save_to_file()
{ofstream outfile("f2.dat");
if(!outfile)
{cerr<<"open f2.dat error!"<<endl;
exit(1);
}
char c[80];
cin.getline(c,80);
for(int i=0;c[i];i++)
if(c[i]>=65 && c[i]<=90||c[i]>=97 && c[i]<=122)
{outfile.put(c[i]);
cout<<c[i];}
cout<<endl;
outfile.close();
}
void get_from_file()
{char ch;
ifstream infile("f2.dat",ios::in);
if(!infile)
{cerr<<"open f2.dat error!"<<endl;
exit(1);
}
ofstream outfile("f3.dat");
if(!outfile)
{cerr<<"open f3.dat error!"<<endl;
exit(1);
}
while(infile.get(ch))
{if(ch>=97 && ch<=122)
ch=ch-32;
outfile.put(ch);
cout<<ch;
}
cout<<endl;
infile.close();
outfile.close();
}
int main()
{save_to_file();
get_from_file();
return 0;
}
2.二进制文件
- 用成员函数read和wirte来读写文件
#include <fstream>
using namespace std;
struct student
{char name[20];
int num;
int age;
char sex;
};
int main()
{student stud[3]={"Li",1001,18,'f',"Fun",1002,19,'m',"Wang",1004,17,'f'};
ofstream outfile("stud.dat",ios::binary);
if(!outfile)
{cerr<<"open error!"<<endl;
abort();
}
for(int i=0;i<3;i++)
outfile.write((char *)&stud[i],sizeof(stud[i]));
outfile.close();
return 0;
}
与文件有关的流函数
成员函数 | 作用 |
---|---|
gcount() | 得到最后一次输入所读入的字节数 |
tellg() | 得到输入文件标记的当前位置 |
tellp() | 得到输出文件位置标记的当前位置 |
seekg(文件中的位置) | 将输入文件位置标记到指定的位置 |
seekg(位移量,参考位置) | 以参考位置为基础来移动若干字节 |
seekp(文件中的位置) | 将输出文件位置标记到指定的位置 |
seekp(位移量,参考位置) | 以参考位置为基础来移动若干字节 |
#include <fstream>
using namespace std;
struct student
{int num;
char name[20];
float score;
};
int main()
{int i;
student stud[5]={1001,"Li",85,1002,"Fun",97.5,1004,"Wang",54,
1006,"Tan",76.5,1010,"ling",96};
fstream iofile("stud.dat",ios::in|ios::out|ios::binary);
if(!iofile)
{cerr<<"open error!"<<endl;
abort();
}
for(i=0;i<5;i++)
iofile.write((char *)&stud[i],sizeof(stud[i]));
student stud1[5];
for(i=0;i<5;i=i+2)
{iofile.seekg(i*sizeof(stud[i]),ios::beg);
iofile.read((char *)&stud1[i/2],sizeof(stud1[i]));
cout<<stud1[i/2].num<<" "<<stud1[i/2].name<<" "<<stud1[i/2].score<<endl;
}
cout<<endl;
stud[2].num=1012;
strcpy(stud[2].name,"Wu");
stud[2].score=60;
iofile.seekp(2*sizeof(stud[0]),ios::beg);
iofile.write((char *)&stud[2],sizeof(stud[2]));
iofile.seekg(0,ios::beg);
for(i=0;i<5;i++)
{iofile.read((char *)&stud[i],sizeof(stud[i]));
cout<<stud[i].num<<" "<<stud[i].name<<" "<<stud[i].score<<endl;
}
iofile.close();
return 0;
}
第十章c++工具
一、异常处理
- c++异常处理机制由三部分组成:检查、抛出、捕获
#include <iostream>
#include <cmath>
using namespace std;
int main()
{double triangle(double,double,double);
double a,b,c;
cin>>a>>b>>c;
try
{while(a>0 && b>0 && c>0)
{cout<<triangle(a,b,c)<<endl;
cin>>a>>b>>c;}
}
catch(double)
{cout<<"a="<<a<<",b="<<b<<",c="<<c<<",that is not a traingle!"<<endl;}
cout<<"end"<<endl;
return 0;
}
double triangle(double a,double b,double c)
{double s=(a+b+c)/2;
if (a+b<=c||b+c<=a||c+a<=b) throw a;
return sqrt(s*(s-a)*(s-b)*(s-c));
}
- 异常处理的语法是:
throw 表达式;
try {被检查的语句}
catch(异常信息类型[变量名]){进行异常处理的语句}
- 注意try和catch之间不能有其他任何代码!!!
二、命名空间
- 在引用多个不知情的文件中,可能会出现名字的冲突,重复定义,从而使用命名空间来解决
- 命名空间的使用方法与类的使用方法差不多
//例14.5中的头文件1,文件名为header11.h
using namespace std;
#include <string>
#include <cmath>
namespace Ns1
{class Student
{public:
Student(int n,string nam,int a)
{num=n;name=nam;age=a;}
void get_data();
private:
int num;
string name;
int age;
};
void Student::get_data()
{cout<<num<<" "<<name<<" "<<age<<endl;
}
double fun(double a,double b)
{return sqrt(a+b);}
}
//例14.5中的头文件2,文件名为header12.h
#include <string>
#include <cmath>
namespace Ns2
{class Student
{public:
Student(int n,string nam,char s)
{num=n;name=nam;sex=s;}
void get_data();
private:
int num;
string name;
char sex;
};
void Student::get_data()
{cout<<num<<" "<<name<<" "<<sex<<endl;
}
double fun(double a,double b)
{return sqrt(a-b);}
}
//main file
#include <iostream>
#include "header11.h"
#include "header22.h"
int main()
{Ns1::Student stud1(101,"Wang",18);
stud1.get_data();
cout<<Ns1::fun(5,3)<<endl;
Ns2::Student stud2(102,"Li",'f');
stud2.get_data();
cout<<Ns2::fun(5,3)<<endl;
return 0;
}
- 变量命名空间 std
三、c++库
-
c传统方法:
- #include<stdio.h>
- #include<math.h>
- #include<string.h>
-
c++新方法:
- #include
- #include
- #include
- using namespace std;