C++学习笔记(六)——C++输入输出流
C++语言的输入输出机制包含3层,前两层是从传统的C语言继承而来,分别是底层I/O和高层I/O,第3层是C++中增添的流类库,这是本章讨论的重点。(1)底层I/O:底层I/O依赖于操作系统来实现,调用操作系统的功能对文件进行输入输出处理,具有较高的速度。底层I/O将外部设备和磁盘文件都等同于逻辑文件,采用相同的方法进行处理,一般过程为“打开文件”、“读写文件”,“关闭文件”,这些是通过一组底层I/O函数来完成的,这些函数定义在头文件io.h中。(2)高层I/O:高层I/O是在底层I/O的基础上扩展起来的,仍旧将外部设备和磁盘文件统一处理,但处理的方式更为灵活,提供的一组处理函数定义在头文件stdio.h中,新的C++标准头文件为,提供的这些函数大体可分为两类:一般文件函数(外部设备和磁盘文件)和标准I/O函数。
C++输入输出流操作对应的库的关系如下图(图一)所示:
标准输入输出流 – 头文件(内置函数如:cin/cout/cerr-- printf/scanf); 文件输入输出流 – 头文件(内置函数如:ifstream/ofstream/fstream fprintf fscanf fopen fwrite fclose); 字符串流 – 头文件(内置函数如:istringstream/ostringstream/stringstream sscanf sprintf)。
标准输入输出流()
首先需要知道流的状态可分为:
- badbit 系统级故障,不可恢复
- failbit 可以恢复的错误
- eofbit 碰到了文件结尾
- goodbit 有效状态
查询流的状态可以通过下面的操作实现: - cin.bad()//1表示系统出现故障,0表示正常
- cin.fail()//1表示出现可恢复错误,0表示正常
- cin.eof()//1表示碰到文件结尾,0表示正常
- cin.good()//1表示有效状态,0表示无效状态
实例代码如下(代码6-1):
///
/// @file io1.cc
/// @date 2019-02-09 22:35:57
///
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::cin;//cin标准输入表达式
using std::string;
void printCinStatus()
{
cout << "cin badbit = " << cin.bad() << endl;
cout << "cin failbit = " << cin.fail() << endl;
cout << "cin eofbit = " << cin.eof() << endl;
cout << "cin goodbit = " << cin.goodbit << endl; //cin.goodbit没有"()"
}
int main()
{
int inum;
printCinStatus();
while(cin >> inum)
{
cout << "inum = " << inum << endl;
}
//
printCinStatus();
cout << endl;
cin.clear();//cin对象是有缓冲区的,使用clear将会重置badbit,failbit,eofbit和goodbit为初始值
printCinStatus();
string s;
cin >> s;
cout << "inum = " << s << endl;
return 0;
}
此示例程序的功能就是将键盘输入的整型数字放到程序中。如果输入的不是整型则cin.failbit()就等于1。示例结果如下图所示(图二)
文件输入输出流
文件输入输出流共有三个库:文件输入输出流;文件输出流和文件输入流,这三个库的关系留作日后研究,现在只讨论对这三个库的一些常用操作。
文件输入输出流
对文件的操作包括如下6种:
ios::in 打开文件做读操作
ios::out 打开文件做写操作,会删除原有数据
ios::app 在每次写之前找到文件尾
ios::trunc 打开文件时清空已存在的文件流
ios::ate 打开文件后立即定位到文件末尾
ios::binary 以二进制模式进行IO操作
使用示例如下代码(代码6-2):
///
/// @file io4.cc
/// @date 2019-02-10 19:07:10
///
#include <iostream>
#include <fstream>
using std::cout;
using std::endl;
using std::cin;
using std::fstream;
using std::ofstream;
void test1()
{
//要求f1.dat文件必须存在,fstream打开的文件就已经默认可以做读写操作了
fstream fs("f1.dat");
if(!fs.good())
{
cout << "open error!" << endl;
return;
}
int inum;
for(size_t idx = 0; idx != 10; ++idx)
{
cin >> inum;
fs << inum << " ";
}
fs.seekg(0,std::ios::beg);//将文件指针移动到文件头
for(size_t idx = 0; idx != 10; ++idx)
{
fs >> inum;
cout << inum << " ";
}
fs.close();
}
int main()
{
test1();
return 0;
}
文件输出流
文件输出流创建的对象就已经默认可以进行写操作,其基本参数与用法与fstream完全相同。实例代码如下(代码6-3):
///
/// @file io4.cc
/// @date 2019-02-10 19:07:10
///
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
using std::ofstream;
void test0()
{
//ofstream ofs("test.txt", std::ios::ate);//ate会将文件清空
ofstream ofs("test.txt", std::ios::app);//写前将文件指针定位到文件尾
if(!ofs.good())
{
cout << "ofstream open error!" << endl;
}
ofs<< "that's new" << endl;
cout << ofs.tellp() << endl;//tellp输出文件指针的位置
ofs.close();
}
int main()
{
test0();
return 0;
}
文件输入流
文件输出流创建的对象就已经默认可以进行读操作,其基本参数与用法与fstream完全相同。实例代码如下(代码6-4):
///
/// @file io3.cc
/// @author XuHuanhuan(1982299154@qq.com)
/// @date 2019-02-10 18:28:24
///
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using std::cout;
using std::endl;
using std::ifstream;
using std::string;
using std::getline;
using std::vector;
int test1()
{
ifstream ifs("io2.cc");
cout << "ifs's badbit = " << ifs.bad() << endl;
cout << "ifs's failbit = " << ifs.fail() << endl;
cout << "ifs's eofbit = " << ifs.eof() << endl;
cout << "ifs's goodbit = " << ifs.good() << endl;
if(!ifs.good())
{
cout << "fistream open file error!" << endl;
return -1;
}
// string word;
// while(ifs >> word)//文件流默认空格作为分隔符,即每读到空格前将字符串传递给word
// {
// cout << word << endl;
// }
string line;
vector <string> lines;
cout << "------------" << endl;
while(getline(ifs,line)) //这里就是一次获取一行
{
//cout << line << endl;
lines.push_back(line);//将line(一行)存入lines中
}
for(int idx = 0; idx << lines.size(); idx++)
{
cout << lines[idx] << endl;
}
ifs.close();//必须要要添加的
return 0;
}
int main()
{
test1();
return 0;
}
字符串输入输出流
字符串输入输出流主要用于格式的转化操作。其类和字符串输入输出流一样由三种:
- stringstream//既可以进行输入也可以进行输出
- istringstream//只能进行输出
- ostringstream//只能进行输入
实例代码如下:
///
/// @file op5.cc
/// @date 2019-02-10 19:59:58
///
#include <iostream>
#include <sstream>
#include <string>
using std::cout;
using std::endl;
using std::stringstream;
using std::string;
//字符串流的作用就是格式转换
//常用于处理配置文件
void test0()
{
int val1 = 512;
int val2 = 1024;
stringstream ss;
ss << "val1 = " << val1 << "val2= " << val2;//将整型转为字符型
string s = ss.str();
cout << s << endl;
int inum;
while(!ss.eof())
{
ss >> s >> inum;
cout << "str: " << s << endl
<< "num: " << inum << endl;
}
}
int main()
{
test0();
return 0;
}