c++中的IO流

C++ 中的IO流
c语言中的输入输出

说到c++就不能不提c语言,在c语言中,依靠输入输出函数进行IO操作,在c语言中我们常用的函数有

scanf printf
pusts gets putc getc
getchar putchar
fwrite fread
...

这些IO函数通过一些缓冲区在设备和代码之间进行数据的输入和输出。缓冲区的读写速度较快,设备和代码都能很快的从其中复制数据和写入数据,从而完成IO操作。

      --->   输入缓冲区  --->
设备                            代码
      <---   输出缓冲区  <---

缓冲区的缓冲方式一般分为三种:

  • 全缓冲:当缓冲区被写满时才进行刷新
  • 行缓冲:当缓冲区遇到换行符时才进行刷新
  • 无缓冲:写入的数据会立即刷新出来
什么是流

在向缓冲区中写入的和读出的数据我们称之为流,流我们可以认为是一个方向向另一个方向流动的数据流,是连续性的,具有方向性的。在c语言中流都是基于缓冲区实现的,他们的区别仅在于输出的方向,和对数据的操作方式不同。

流可以分为两种:

  • 文本流:在缓冲区中读出和写入时是基于ASCII或者Unicode字符编码的。写入缓冲区的最大长度规定为254个字符。在文本文件结束时规定以一个回车符和换行符结尾,在写入缓冲区时,会将\n转换为回车换行符,在从缓冲区中读取出数据时,就会将回车换行符转换为换行符。
  • 二进制流:二进制的流在向缓冲区中写入或读出文件时,不进行字符的转换,直接从设备或文件中读取,在这个过程中不发生任何改变,原先是什么样子,读取之后还是什么样子,它是基于二进制数字啊的。

在c语言中,每个运行时系统必须提供三个标准流 标准输入stdin 标准输出stdout 标准错误stderr
stdin为缺省时的输入设备,一般为键盘, stdout为缺省时的输出设备,一般对应屏幕,stderr为输出错误信息的,一般也对应到屏幕。当然这些都是默认缺省时的,我们可以自行通过重定向来改版输出输入的方向。

c++中的IO流

在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++在类库中定义了四个全局流的对象:

  • cin : 标准输入流,对应键盘
  • cout:标准输出流,对应显示器
  • clog:标准输出错误流,对应显示器
  • cerr:标准输出错误流,对应显示器

注意:

  • 使用cin输入时,从键盘输入的数据会存放在键盘的缓冲区,当我们按下回车时,就会将其送入输入缓冲区。所以对输入的修改只能在按下回车之前。一旦按下回车就无法修改,因为在输入缓冲区中,只有当数据被全部取完时,需要重新输入,写入缓冲区的数据,会顺序依次被取出,无法删除。
  • 输入与输出的数据的类型必须一致,否则会报错。出错时会在status状态字的对应位置置1,程序继续运行。
  • 使用cin数据的分隔可以使用空格或者是回车,对于cin输入数据时,空格 回车 TAB等键是不可见的。但在对于字符型或字符串进行输入时,字符串中不能有空格,而且回车符也无法起作用.当遇到回车时就直接结束,遇到空格后,之后输入的字符无效。

c++中的IO流_第1张图片

c++中的文件流

在c++中有两种文件格式,根据数据的类容进行分类,一种是文本文件,一种是二进制文件。在类库中也实现了对文件操作的类。

fstream库中有 三个类流

  istream -----> ifstream
  ostream -----> ofstream
  iostream ----> fstream
  • ifstream 支持从磁盘文件输入
  • ofstream 支持向磁盘文件输出
  • fstream 支持从磁盘文件输入和输出

我们需要创建一个流对象来进行操作,cin cout等流对象是在iostream中创建好的。

ifstream inputfile;
ofstream outputfile;
fstream iofile;

//定义三个文件流对象

对于文件操作和c语言一样,在类中有关于打开,关闭,写入,和读出的对文件操作的成员函数。

【1】打开文件:将一个流对象与一个文件相关联

  • 通过构造函数
std::ofstream ofile("test1.txt",std::ofstream::out);
//参数:文件名  请求标志位
  • 使用成员函数open
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
流对象直接调用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;
}

你可能感兴趣的:(C++)