前言
大家好,我是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流
C++系统实现了一个庞大的类库,其中ios为基类,其他类都是直接或间接派生自ios类。
C++标准库提供了4个全局流对象cin、cout、cerr、clog,使用cout进行标准输出,即数据从内存流向控制台(显示器)。使用cin进行标准输入即数据通过键盘输入到程序中,同时C++标准库还提供了cerr用来进行标
准错误的输出,以及clog进行日志的输出,从上图可以看出,cout、cerr、clog是ostream类的三个不同的对象。
注意
- cin为缓冲流。键盘输入的数据保存在缓冲区中,当要提取时,是从缓冲区中拿。如果一次输入过多,会留在那儿慢慢用,如果输入错了,必须在回车之前修改,如果回车键按下就无法挽回了。只有把输入缓冲区中的数据取完后,才要求输入新的数据
- 空格和回车都可以作为数据之间的分格符,所以多个数据可以在一行输入,也可以分行输入。但如果是字符型和字符串,则空格(ASCII码为32)无法用cin输入,字符串中也不能有空格。回车符也无法读入
- 输入的数据类型必须与要提取的数据类型一致,否则出错。出错只是在流的状态字state中对应位置位(置1),程序继续。
C++根据文件内容的数据格式分为二进制文件和文本文件,ifstream (只输入用)、ofstream(只输出用)、fstream(既输入又输出用)。
文本写文件
- 包含头文件:#include
- 创建文件流对象: ofstream ofs;
- 以写入方式打开文件:ofs.open(“文件路径”,ios::out);
- 写入内容:ofs<<“写入内容”;
- 关闭文件:ofs.close();
#include<iostream>
#include<fstream>
using namespace std;
void()
{ofstream ofs;ofs.open("test.txt", ios::out);ofs << "hello world" << endl;ofs.close();return 0;
}
文本读文件
-
包含头文件:#include
-
创建流对象:ifstream ifs;
-
以读取模式打开文件:ifs.open(“文件路径+文件名/文件名”,ios::in)
-
读取数据:常用的有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;}
}
二进制写
-
包含头文件:#include
-
创建文件流:ofstream ofs;
-
以二进制方式打开文件:
ofs.open(“文件名”,ios::binary|ios::out);
-
写入数据:调用成员函数
ostream& write(const char * buffer,int len); ofs.write((const char*)ptr,sizeof(*ptr));
字符指针buffer指向内存中一段储存空间,len是要写入字节数。
-
关闭文件:ofs.close();
二进制读
-
包含头文件:#include
-
创建文件流:ifstream ifs;
-
以二进制方式打开文件:
ifs.open(“文件名”,ios::binary|ios::in);
-
读取数据:
调用成员函数ifstream& read((char*)buf,sizeof(buf));
buf是读取内容的缓存区强转为(char*),按照单个字节计算读取内容。
-
关闭文件: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;*/
}