c++IO

前言

大家好,我是jiantaoyab,本篇文章给大家介绍c++中文件操作。

先回忆一下c语言文件操作

void Test_c_bin()
{
	//二进制写
	ServerInfo info = { "127.0.0.1", 8080 };
	FILE* fout = fopen("test.bin", "wb");
	fwrite(&info, sizeof(info), 1, fout);
	//二进制读 
	FILE* fin = fopen("test.bin", "rb");
	ServerInfo info;
	fread(&info, sizeof(info), 1, fin);
	std::cout << info._ip << ":" << info._port << std::endl;
}

void Test_c_text()
{
	//文本写
	ServerInfo info = { "127.0.0.1", 8080};
	FILE* fout = fopen("test.txt", "w");
	fprintf(fout, "%s\n%d", info._ip, info._port);
	
	//文本读
	ServerInfo info;
	FILE* fin = fopen("test.txt", "r");
	fscanf(fin,"%s%d", info._ip, &info._port);
	printf("%s:%d\n", info._ip, info._port);
}

再看看c++中流的概念,是对一种有序连续且具有方向性的数据(单位可以是bit,byte,packet 的抽象描述。C++流是指信息从外部输入设备(如键盘)向计算机内部(如内存)输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为“流”。它的特性是:有序连续、具有方向性。为了实现这种流动,C++定义了I/O标准类库,这些每个类都称为流/流类,用以完成某方面的功能。

c++ IO流

image-20240420113303615

C++系统实现了一个庞大的类库,其中ios为基类,其他类都是直接或间接派生自ios类。

C++标准库提供了4个全局流对象cin、cout、cerr、clog,使用cout进行标准输出,即数据从内存流向控制台(显示器)。使用cin进行标准输入即数据通过键盘输入到程序中,同时C++标准库还提供了cerr用来进行标
准错误的输出,以及clog进行日志的输出,从上图可以看出,cout、cerr、clog是ostream类的三个不同的对象。

注意

  1. cin为缓冲流。键盘输入的数据保存在缓冲区中,当要提取时,是从缓冲区中拿。如果一次输入过多,会留在那儿慢慢用,如果输入错了,必须在回车之前修改,如果回车键按下就无法挽回了。只有把输入缓冲区中的数据取完后,才要求输入新的数据
  2. 空格和回车都可以作为数据之间的分格符,所以多个数据可以在一行输入,也可以分行输入。但如果是字符型和字符串,则空格(ASCII码为32)无法用cin输入,字符串中也不能有空格。回车符也无法读入
  3. 输入的数据类型必须与要提取的数据类型一致,否则出错。出错只是在流的状态字state中对应位置位(置1),程序继续。

C++根据文件内容的数据格式分为二进制文件和文本文件,ifstream (只输入用)、ofstream(只输出用)、fstream(既输入又输出用)。

文本写文件

  1. 包含头文件:#include
  2. 创建文件流对象: ofstream ofs;
  3. 以写入方式打开文件:ofs.open(“文件路径”,ios::out);
  4. 写入内容:ofs<<“写入内容”;
  5. 关闭文件:ofs.close();

image-20240420114040616

#include<iostream>
#include<fstream>
using namespace std; 
void()
{
	ofstream ofs;
	ofs.open("test.txt", ios::out);
	ofs << "hello world" << endl;
	ofs.close();
	return 0;
}

文本读文件

  1. 包含头文件:#include

  2. 创建流对象:ifstream ifs;

  3. 以读取模式打开文件:ifs.open(“文件路径+文件名/文件名”,ios::in)

  4. 读取数据:常用的有4中方法

    • ifs>> int,char,float,char *,string 等等。可读取整形、浮点型、字符型、字符串等等,读取字符串时可将读取内容存入字符数组,也可存入string;读取字符串时一次读一行,遇到空格、制表符、换行符或读取到字符数组长度-1个字符时返回。读取成功返回istream&,读取失败返回false。

    • ifs.getline(char *buf,int size,char delim=‘\n’);

      一次读取一行,存入字符数组;遇到换行符或者读取到sizeof(buf)-1个字符返回(最后一个字符需要自动添加结束字符\0);遇到限定字符delim提前返回。读取失败返回false。

    • getline(istream& ifs,string& str,char delim=‘\n’);一次读取一行,存入字符串;遇到换行符和限定字符delim提前返回。读取失败返回false。

    • int get();/ istream& get(char *buf, int size,char delim=‘\n’);/istream& get(char c)

      常用的ifstream成员get函数有这几种重载;同样读取内容存入字符数组时遇到限定字符delim时提前返回,后面两种读取失败返回false。

#include<iostream>
#include<fstream>
using namespace std;
#include<string>
//方法1
void func(ifstream& ifs, string buf) {
	while (ifs >> buf) {
		cout << buf << endl;
	}
}
//方法2
void func(ifstream& ifs, char buf[1024]) {
	while (ifs.getline(buf, 1024)){
		cout << buf1 << endl;
	}
}
//方法3
void func(ifstream& ifs, string& buf) {
	while (getline(ifs, buf)) {
		cout << buf << endl;
	}
}
//方法4
void func(ifstream& ifs, char c) {
	while (ifs.get(c)) {
		cout << c;
	}
}

二进制写

  1. 包含头文件:#include

  2. 创建文件流:ofstream ofs;

  3. 以二进制方式打开文件:

    ofs.open(“文件名”,ios::binary|ios::out);

  4. 写入数据:调用成员函数

    ostream& write(const char * buffer,int len); ofs.write((const char*)ptr,sizeof(*ptr));

    字符指针buffer指向内存中一段储存空间,len是要写入字节数。

  5. 关闭文件:ofs.close();

二进制读

  1. 包含头文件:#include

  2. 创建文件流:ifstream ifs;

  3. 以二进制方式打开文件:

    ifs.open(“文件名”,ios::binary|ios::in);

  4. 读取数据:

    调用成员函数ifstream& read((char*)buf,sizeof(buf));

    buf是读取内容的缓存区强转为(char*),按照单个字节计算读取内容。

  5. 关闭文件:ifs.close();

写成一个类

#include<iostream>
#include<string>
#include<fstream>

struct ServerInfo
{
	char _ip[32];
	int _port;
};

//ifstream 输入 ofstream 输出
class Config
{
public:
	Config(const char* filename)
		:_filename(filename)
	{}
	void WriteBin(ServerInfo& info)
	{
		std::ofstream ofs(_filename.c_str(), std::ios_base::out | std::ios_base::binary);
		ofs.write((const char*)&info, sizeof(ServerInfo));
	}
	void ReadBin(ServerInfo& info)
	{
		std::ifstream ifs(_filename.c_str(), std::ios_base::in | std::ios_base::binary);
		ifs.read((char*)&info, sizeof(ServerInfo));
	}

	void WriteText(ServerInfo& info)
	{
		std::ofstream ofs(_filename.c_str());
		ofs << info._ip <<" "<< info._port;
		
	}
	void ReadText(ServerInfo& info)
	{
		std::ifstream ifs(_filename.c_str());
		ifs >> info._ip >> info._port;
		
	}
private:
	std::string _filename;
};

int main()
{
	ServerInfo info = { "127.0.0.1", 8080 };
	//Test_c_bin();
	//Test_c_text();

	//二进制
	//Config cm("config.bin");
	//cm.WriteBin(info);
	//cm.ReadBin(info);
	//std::cout << info._ip << ":" << info._port << std::endl;

	//文本
	/*Config cm("config.bin");
	cm.WriteBin(info);
	cm.ReadBin(info);
	std::cout << info._ip << ":" << info._port << std::endl;*/
}
  • 20
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值