C++文件IO

一、I/O流

​ C++把对文件的读写操作都封装在了以下类中:

​ ofstream 对文件的写操作,继承了ostream类的功能

​ ifstream 对文件的读操作,继承了istream类的功能

​ fstream 对文件的读写操作,继承了ofstream、ifstream类的功能

二、C++对文件进行读写的步骤:

1、创建流对象,打开文件
#include <fstream>
void open( const char *filename);
void open( const char *filename, openmode mode);
功能:用于打开文件,且类的构造函数与它们参数一样。
    filename:文件的路径
    mode:打开方式
        ios::app 添加输出 
        ios::ate 当已打开时寻找到EOF 
        ios::binary 以二进制模式打开文件 
        ios::in 为读取打开文件 
        ios::out 为写入打开文件 
        ios::trunc 覆盖存在的文件   
        ifstream 类的默认mode
            只读打开文件,文件不存在则打开失败 r
        ofstream 类的默认mode
            只写打开文件,文件不存在则创建,文件存在则清空。 w
        fstream 类的默认mode r+
            以读写打开文件,文件不存在则打开失败
        注意:这些打开模式单独使用和混合使用的功能有相就的删减,不是简单的功能相加,具体功能可使用 strace 追踪它们底层调用open函数对应
2、判断文件是否打开成功

​ bool good();
​ 功能:判断上一次操作是否成功,可用于判断文件是否打开。
​ 返回值:
​ true:打开成功
​ false:打开失败

3、流对象<< 写操作、流对象>> 读操作

​ ofs << str << endl;
​ ifs >> str;

4、关闭文件

​ void close();

练习1:设计一个学生类并创建对象,然后把对象以文本格式写入stu.txt文件中。
练习2:从stu.txt文件中读写学生类并显示。

注意:在读写类对象时,由于绝大多数成员都是private属性,因此不能在类外进行读写,且由于ostream/istream是ifstream/ofstream/fstream的父类,因此实现<</>>运算符函数既可以用于输入输出对象,也可以用于文本格式的读写。

三、随机读写

C++为流提供了两套设置位置指针的成员函数,为了兼容有两个位置指针系统,但由于Linux和windows系统底层只有一个位置指针,所以使用其中套即可。

istream &seekg( off_type offset, ios::seekdir origin );
功能:偏移值+基础位置设置输入流的位置指针    
origin:        
	ios::beg 文件开头
    ios::end 文件末尾
    ios::cur 当前位置    
    
istream &seekg( pos_type position);    
功能:按绝对位置设置输入流的位置指针
    
ostream &seekp( off_type offset, ios::seekdir origin );    
功能:偏移值+基础位置设置输出流的位置指针    

ostream &seekp( pos_type position );    
功能:按绝对位置设置输出流的位置指针

pos_type tellg();    
功能:获取输入流的位置指针

pos_type tellp();
功能:获取输出流的位置指针
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;

class Student
{
	char name[20];
	char sex;
	short age;
public:
	Student(const char* name,char sex,short age):sex(sex),age(age)
	{
		strcpy(this->name,name);
	}
	friend ostream& operator<<(ostream& os,const Student& stu)
	{
		return os << stu.name << " " << stu.sex << " " << stu.age;
	}
	friend istream& operator>>(istream& is,Student& stu)
	{
		return is >> stu.name >> stu.sex >> stu.age;
	}
};

int main(int argc,const char* argv[])
{
	Student stu("hehe",'m',28);
	fstream fs("text.txt");
	if(!fs.good())
		return -1;
	fs << stu << endl;
	Student stu1("",'w',0);
	fs.seekg(0,ios::beg);
	fs >> stu1;
	cout << stu1 << endl;
  
	fs.close();
}

四、C++对二进制文件进行读写

1、打开文件
使用构造函数,open函数打开文件,mode参数增加ios::binary。    

2、读写        
istream &read( char *buffer, streamsize num );        
buffer:存储数据的缓冲区首地址        
num:缓冲区的大小
        
streamsize gcount();        
功能:获取最后一次读到的字节数
        
ostream &write( const char *buffer, streamsize num );        
buffer:待写入数据的内存首地址        
num:数据的字节数        

使用good函数判断是否写入成功。    

3、关闭文件        
void close();    
注意:在写入对象时,对象的成员中不应该有指针(string)类型的成员。

bool eof();    
功能:判断文件是否到达末尾
	while(true)    
	{        
		// 读操作 fs>>obj fs.read
   	 	if(fs.eof())break;
        // 其它操作    
    }
int main(int argc,const char* argv[])
{
	fstream fs("stu.dat",ios::binary|ios::out|ios::in);
	if(!fs.good())
		cout << "打开失败!" << endl;
	fs.seekg(0,ios::end);
	
	Student* stu = new Student("hehe",'m',18);
	Student* stu1 = new Student("",'w',0);
	
	fs.write((char*)stu,sizeof(Student));
	fs.seekg(0,ios::beg);
	fs.read((char*)stu1,sizeof(Student));
	cout << *stu1 << endl;
	cout << fs.gcount() << endl;
	
	char buf[4096] = {};
	fs.seekg(0,ios::beg);
	while(true)
	{
		fs.read((char*)stu1,sizeof(Student));
		cout << *stu1 << endl;
		if(fs.eof()) break;
	}
	fs.close();
}

五、类型信息

​ C++中的typeid可以获取数据的类型,使用时需要加头文件typeinfo。
​ 1、返回值是type_info类型对象
​ 2、type_info的name成员函数可以获取类型名
​ 3、它还实现了==运算符,可以判断两个数据是否是同一种类型。
​ 4、它可以区别父类指针或引用指向的是哪个子类,但前提是父子类之间构造了多态。

作业:实现一个C++版mv命令。

​ stat
​ 移动文件
​ 源文件是普通文件
​ 重命名 目标不能被打开
​ 不重命名 目标能打开
​ 目标是目录
​ 目标是文件,是否覆盖
​ 重命名
​ 源文件和目标文件在同目录下
​ 目录移动

#include <iostream>
#include <fstream>
using namespace std;

int main(int argc,const char* argv[])
{
	if(3 != argc)
	{
		cout << "Use:mv <src> <dest>" << endl;
		return -1;
	}

	ifstream ifs(argv[1]);
	if(!ifs.good())
	{
		cout << "源文件不存在,请检查" << endl;
		return -1;
	}

	if(0==access(argv[2],F_OK))
	{
		cout << "源文件已存在,是否覆盖(y/n)?";
		char cmd;
		cin >> cmd;
		if(cmd != 'y')
		{
			cout << "停止移动!" << endl;
			ifs.close();
			return 0;
		}
	}

	ofstream ofs(argv[2]);
	if(!ofs.good())
	{
		cout << "目标位置无权限,请检查!" << endl;
		return -1;
	}

	char buf[4096];
	do{
		ifs.read(buf,sizeof(buf));
		ofs.write(buf,ifs.gcount());
	}while(!ifs.eof());

	ifs.close();
	ofs.close();

	remove(argv[1]);
}

可以写在简历中的小工具
mv命令
ping命令
rm -rf命令
ls -la命令
cp多线程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值