在计算机内存中数据从一个地址移动到另一个地址的过程称为数据流动——流操作。
流操作是通过内存中的一块缓冲区实现文件与内存之间的数据交换(缓冲文件的读取速度和内存数据的读取速度之间的差距)
一、头文件
- iostream(iostream.h) : 包含输入、输出流所需的所有信息含有cin、cout、cerr、clog对象,提供无格式和格式化的I/O
- iomanpi.h :用于指定数据输入输出的格式
- fstream.h :处理文件信息,包括建立文件,读写文件等各种操作
二、输出流
输出运算符“<<",左操作数为输出流ostream的对象cout,右边为一个基本数据类型。
eg:cout << n ;
可以重载"<<" 输出结构变量或类对象,重载格式为:
ostream &operater<<(ostream &os, 类名 该类的一个对象名){
对该对象的输出操作;
return os;
}
注意:
- 运算符<<只能使用友元重载(因为<<的左操作数必须是ostream的对象,如果是成员函数则要求左操作数是该类的一个对象)
- 重载运算符返回值应该是一个ostream对象的引用(这样才能连续输出多个对象)
#include<iostream>
using namespace std;
class point{
private:
float x,y,z;
public:
point(float a=0,float b=0,float c=0){
//默认构造函数
x=a;y=b;z=c;
}
firend ostream &operator<<(ostream &os,point p){
//友元声明
//重载运输符<<,左操作数为ostream的对象,右操作数为point类的对象
os<<"("<<p.x<<","<<p.y<<","<<p.z<<","<<")\n";
return os;
//返回输出流ostream的一个引用对象,即cout。
}
};
int main(){
point p1(1,2,3),p2(4,5,6),p3(7,8,9);
cout<<p1<<p2<<p3<<endl;
return 0;
}
三、输入流
输入运算符">>" 左操作数是istream 的对象cin,右边是一个基本数据类型。
对输入运输符的重载与输出运算符类似,返回时返回istream的引用对象:
friend istream &operater>>(istream &is,point &p){
is>>p.x;
is>>p.y;
is>>p.z;
return is;
}
对>>的重载同样需要以友元的方式进行。
四、输入输出的格式控制
函数原型 | 功能 |
long ios_base::setf(long flags); | 设置状态标志flags |
long ios_base::unsetf(long flags); | 清除状态标志,并返回清除前的标志 |
long ios_base::flags(); | 测试状态标志 |
long ios_base::flags(long flags); | 设置flags并返回设置前标志 |
int ios_base::width(); | 返回当前宽度的设置值 |
int ios_base::width(int w); | 设置域宽w并返回以前的设置 |
int ios_bace::precision(int p); | 设置小数位数,并返回以前的小数位数 |
char ios::fill(); | 返回当前的填充字符 |
char ios::fill(char ch); | 设置填充字符ch,并返回当前填充字符 |
使用操作符进行输入输出格式的控制
头文件为iostream的操作符
- dec 以十进制输入输出整形数
- hex 以十六进制输入输出整形数
- oct 以八进制输入输出整形数
- ws 输入时跳过开头的空白符
- endl 输出换行
- ends 插入空字符,结束输出
头文件为iomanip的操作符
- flush 刷新输入流
- setback(int n)将转换基数设置为n(n的取值为0,8,10,16)n的缺省值为0(以十进制输出)
- setfill(char c) 设置填充字符
- setprecision(int n)设置数据小数位数,缺省时为6
- setw(int n) 设置域宽
例子:
#include<iostream>
#include<iomanip>
using namespace std;
int main() {
double values[] = { 1.23,35.36,653.7,4358.24 };
for (int i = 0; i < 4; i++) {
cout.width(10);//用width设置位宽
cout << values[i] <<endl;
}
cout<<endl;//换行
for (int i = 0; i < 4; i++) {
cout.width(10);
cout.fill('*');//字符填充
cout << values[i] << endl;
}
cout << endl;
cout.fill(' ');
char name[] = { 'L','W','C','Z' };
for (int i = 0; i < 4; i++) {
cout << setw(6) << name[i]<<setw(10)<<values[i]<<endl;//用setw设置位宽
}
cout << endl;
for (int i = 0; i < 4; i++) {
cout << setiosflags(ios::left) << setw(6) << resetiosflags(ios::left) << setw(6) << values[i] << endl;//用setiosflags设置左对齐,用resetiosflags设置右对齐
}
}
编译结果:
五、文件的输入输出流
在程序中进行文件操作时需要加上头文件 fstream.h
若要打开文件进行读写操作者必须定义相对应的流对象:
- ifstream in ;//文件输入流对象
- ofstream out; //文件输出流对象
- fstream both; //文件输入/输出流对象
文件的打开与关闭
文件打开用成员函数open()
函数 | 功能 |
ios::ate | 以添加的方式打开 |
ios::in | 作为输入文件 |
ios::out | 作为输出文件 |
ios::trunc | 若文件存在,清除文件内容 |
ios::nocreate | 若文件不存在,返回错误 |
ios::noreplace | 若文件存在,返回错误 |
ios::binary | 以二进制方式打开 |
例:
#include<iostream>
#include<fstream>
using namespace std;
int main() {
ifstream f1; //定义文件输入流对象,用只读的方式打开
f1.open("d:\\vcprg\\test.cpp"); //打开该路径下的文件
char c;
while (f1) {
//判断文件是否结束
f1.get(c); //读出文件中的字符
cout << c; //输出读到的字符
}
cout << endl;
f1.close(); //关闭文件
}
#include<iostream>
#include<fstream>
using namespace std;
//复制文件
int main() {
ifstream f1; //定义文件输入对象,以只读的方式
ofstream f2; //以写的方式
f1.open("d:\\vcprg\\text.cpp"); //以读方式打开文件
f2.open("d:\\vcprg\\text.txt"); //以写的方式打开文件
char c;
while (f1) {
//判断文件是否结束
f1.get(c);
f2 << c; //写入从f1中读出的c
}
cout << "文件复制成功" << endl;
f1.close();//关闭文件
f2.close();
return 0;
}