IO是输入input输出output的首字母缩写形式,直观意思是计算机输入输出。
一、C++IO流
和C语言的scanf 、printf 、fread 、fwrite 等IO类似,C++有自己的IO接口。 C++系统实现了一个庞大的类库,这个库叫做IO流,其中ios为基类,其他类都是直接或间接派生自ios类:
1.1. C++标准IO流
C++标准库提供了4个全局流对象cin、cout、cerr、clog,使用cout进行标准输出,即数据从内存流向控制台(显示器)。使用cin进行标准输入即数据通过键盘输入到程序中,同时C++标准库还提供了cerr用来进行标准错误的输出,以及clog进行日志的输出,从上图可以看出,cout、cerr、clog是ostream类的三个不同的对象,因此这三个对象现在基本没有区别,只是应用场景不同。
在使用时候必须要包含文件并引入std标准命名空间。
cin和cout可以直接输入和输出内置类型的数据。因为标准库已经将所有内置类型的输入和输出进行了重载:
对于持续输入: C语言的写法:
while (scanf("%d", &a) != EOF)
{
}
C++的写法:
while (cin >> a)
{
}
对于终止输出,则是Ctrl+C 的组合
cin >> 返回值的类型是basic_istream&,代表cin的地址。在ios.h文件中定义了类型转换函数:
有这个函数定义后,需要时ios 类型转换成void* 类型。而在读入发生错误时返回0。
1.2. C++文件IO流
和C语言一样,C++根据文件内容的数据格式将文件分为二进制文件和文本文件。 C++采用文件流对象操作文件的一般步骤如下:
- 定义一个文件流对象。
操作文件的类有以下三个:
类 | 对应操作场景 |
---|
ofstream | 只写 | ifstream | 只读 | fstream | 读+写 |
- 使用文件流对象的成员函数打开一个磁盘文件,使得文件流对象和磁盘文件之间建立联系。
文件常见的打开方式如下:
打开方式 | 功能 |
---|
in | 以读的方式打开文件 | out | 以写的方式打开文件 | binary | 以二进制方式对文件进行操作 | ate | 输出位置从文件的末尾开始 | app | 以追加的方式对文件进行写入 | trunc | 先将文件内容清空再打开文件 |
- 使用提取和插入运算符对文件进行读写操作,或使用成员函数进行读写。
对文件进行提取和插入操作的常用成员函数:
成员函数 | 功能 |
---|
put | 插入一个字符到文件 | write | 插入一段字符到文件 | get | 从文件提取字符 | read | 从文件提取多个字符 | tellg | 获取当前字符在文件当中的位置 | seekg | 设置对文件进行操作的位置 | >>运算符重载 | 将数据形象地以“流”的形式进行输入 | <<运算符重载 | 将数据形象地以“流”的形式进行输出 |
close() 关闭文件。
使用>>和<<对文件进行读写
相比于其他对文件操作的函数,>> 和<< 对文件进行读写操作,会变得很简单,也很形象:
1.3. 将日期类写入文件并从文件中读取
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
class Date
{
public:
Date()
{
}
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
int _year;
int _month;
int _day;
};
int main()
{
vector<Date>v;
v.push_back(Date(10, 10, 5));
v.push_back(Date(11, 10, 5));
v.push_back(Date(6, 10, 5));
v.push_back(Date(1, 10, 5));
ofstream ofs("data.txt",fstream::app);
for (auto& e : v)
{
ofs << e._year << " " << e._month << " " << e._day << endl;
}
vector<Date>v1;
ifstream ifs("data.txt");
Date temp;
while (ifs >> temp._year&& ifs >> temp._month&& ifs >> temp._day)
{
v1.push_back(temp);
}
for (auto& e : v1)
{
cout << e._year << "-" << e._month << "-" << e._day << endl;
}
}
二、stringstream
在C语言中,我们若是想要将一个整型变量的数据转化为字符串格式,有以下两种方法:
-
使用_itoa 函数进行转化。 -
使用sprintf函数进行转化。
这两种方法在使用之前都需要先给出保存结果的空间,而空间的大小是不太好界定的,除此之外,转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。 在C++中,可以使用stringstream类对象来避开此问题。
在程序中如果想要使用stringstream,必须要包含头文件<sstream> 。在该头文件下,标准库三个类:istringstream、ostringstream 和 stringstream,分别用来进行流的输入、输出和输入输出操作。
注意:
- stringstream实际是在其底层维护了一个string类型的对象用来保存结果。
- 多次数据类型转化时,一定要用clear()来清空,才能正确转化,但clear()不会将stringstream底层的
string对象清空。 - 可以使用s. str("")方法将底层string对象设置为""空字符串。
- 可以使用s.str()将让stringstream返回其底层的string对象。
- stringstream使用string类对象代替字符数组,可以避免缓冲区溢出的危险,而且其会对参数类型进行推演,不需要格式化控制,也不会出现格式化失败的风险,因此使用更方便,更安全。
|