说到c++就不能不提c语言,在c语言中,依靠输入输出函数进行IO操作,在c语言中我们常用的函数有
scanf printf
pusts gets putc getc
getchar putchar
fwrite fread
...
这些IO函数通过一些缓冲区在设备和代码之间进行数据的输入和输出。缓冲区的读写速度较快,设备和代码都能很快的从其中复制数据和写入数据,从而完成IO操作。
---> 输入缓冲区 --->
设备 代码
<--- 输出缓冲区 <---
缓冲区的缓冲方式一般分为三种:
在向缓冲区中写入的和读出的数据我们称之为流,流我们可以认为是一个方向向另一个方向流动的数据流,是连续性的,具有方向性的。在c语言中流都是基于缓冲区实现的,他们的区别仅在于输出的方向,和对数据的操作方式不同。
流可以分为两种:
在c语言中,每个运行时系统必须提供三个标准流 标准输入stdin 标准输出stdout 标准错误stderr
stdin为缺省时的输入设备,一般为键盘, stdout为缺省时的输出设备,一般对应屏幕,stderr为输出错误信息的,一般也对应到屏幕。当然这些都是默认缺省时的,我们可以自行通过重定向来改版输出输入的方向。
在c++中有三种的IO操作 标准IO 文件IO 串IO
标准IO:兼容了C中的标准的输入输出,以键盘和屏幕为操作对象,从键盘输入或从屏幕输出
文件IO:以磁盘文件为输入输出的对象,数据在磁盘中写入和读出
串IO:对内存中指定的空间进行输入和输出。通常指定一个字符数组作为存储空间(实际上可以利用该空间存储任何信息)。这种输入和输出称为字符串输入输出,简称串I/O。
c++的IO操作编译时会对类型严格的检查,所以c++的IO是类型安全的,而c语言中的输入输出并不是类型安全的。
在c++中为了实现这些IO操作,定义了一个标准的IO类库,而在库中的这些类被称为流或流类。这些类可以对基本类型进行输入输出,也可以对自定义的类型进行输入输出,这些类体现了c++标准IO库的可扩展性。
c++通过这个类库来实现自己的IO流操作。
在这个类库中,所有的类都直接或间接继承于一个抽象的基类ios。
c++在类库中定义了四个全局流的对象:
注意:
在c++中有两种文件格式,根据数据的类容进行分类,一种是文本文件,一种是二进制文件。在类库中也实现了对文件操作的类。
fstream库中有 三个类流
istream -----> ifstream
ostream -----> ofstream
iostream ----> fstream
我们需要创建一个流对象来进行操作,cin cout等流对象是在iostream中创建好的。
ifstream inputfile;
ofstream outputfile;
fstream iofile;
//定义三个文件流对象
对于文件操作和c语言一样,在类中有关于打开,关闭,写入,和读出的对文件操作的成员函数。
【1】打开文件:将一个流对象与一个文件相关联
std::ofstream ofile("test1.txt",std::ofstream::out);
//参数:文件名 请求标志位
std::ofstream ofile;
ofile.open("test1.txt",std::ofstream::out)
如果该文件已经打开,open会调用失败
在使用时,每个类都有对于文件的访问权限操方式的限制,输入输出的请求标志
标志 | ||
---|---|---|
in | input | 打开文件读,内部流缓冲区支持输入操作 |
out | output | 文件打开供写入,内部流缓冲区支持输出操作 |
binary | binary | 执行二进制操作 |
app | append | 追加,所有的操作都发生在文件的末尾 |
ate | at end | 输出位置在文件的末尾 |
trunc | trucate | 打开文件之前存于文件之中的内容都会被丢弃 |
文件打开默认位文本文件
权限标志位之间可以使用|进行组合
ofstream 的流对象默认是out ifstream 默认是in 所以可以不用写
【2】关闭文件
断开当前文件与流对象之间的关联。
流对象直接调用close
ufile.close();
如果当前流对象没有打开文件,则调用时就会失败
【3】在对文本文件进行操作时可以用插入 >> 运算符和 提取 << 运算符进行
ostream ofile("test1.txt",std::ofstream::out);
ofile << "sdasdas"; //表示向文件中输入一个数
char a[1024];
istream ifile("test1.txt",std::ifstream::in);
ifile >> a; //将文件中的数据写入a中
【4】写入
ofstream 类中提供了write成员函数,用于向文件中写入数据。
ostream& write (const char* s, streamsize n);
【5】读取
ifstream 类中提供了read成员,用于从文件中读取数据
istream& read (char* s, streamsize n);
在对二进制读写时,我们采用write 和 read 成员函数进行操作。
在类中还提供了一些其他的成员函数入 put() get()
等。
istream& get (char& c); //支持从流中读取单个字符
//get 还有其他的重载函数,可以指出字符串 数据块的获取
ostream& put (char c); //将单个字符插入到流中
使用文件流进行操作的例子:
//写一个简单的配置文件,分别使用二进制和文本模式
#pragma warning(disable:4996)
#include
#include
#include
#include
#include
using namespace std;
struct Config{
int port;
char ch[20];
};
class ConfigManage{
public:
ConfigManage(const string& cogn = "test1.config")
:_configname(cogn)
{}
void WriteBin( Config& wr){
ofstream ofile(_configname, ofstream::binary);
ofile.write((const char*)&wr, sizeof(wr));
ofile.close();
}
void ReadBin(Config& rd){
ifstream ifile(_configname, istream::binary);
ifile.read((char*)&rd, sizeof(rd));
ifile.close();
}
void WriteTxt(Config& wr){
ofstream ofile(_configname);
ofile << wr.ch << endl;
ofile << wr.port << endl;
}
void ReadTxt(Config& rd){
ifstream ifile(_configname);
ifile >> rd.ch;
ifile >> rd.port;
ifile.close();
}
private:
string _configname;
};
int main(){
Config wr;
Config rd;
strcpy(wr.ch, "127.0.0.001");
wr.port = 101;
ConfigManage file("test2.dat");
file.WriteBin(wr);
file.ReadBin(rd);
cout << rd.ch << endl;
cout << rd.port << endl;
ConfigManage file2("test3.txt");
file2.WriteTxt(&wr);
file2.ReadTxt(&rd);
cout << rd.ch<< endl;
cout << rd.port << endl;
return 0;
}