C++文件和流

C++文件的读写流用的是fstream库,它定义了三个新的数据类型:

数据类型 描述
ofstream 该数据类型表示输出文件流,用于创建文件并向文件写入信息。
ifstream 该数据类型表示输入文件流,用于从文件读取信息。
fstream 该数据类型通常表示文件流,且同时具有 ofstream 和 ifstream 两种功能,这意味着它可以创建文件,向文件写入信息,从文件读取信息。

打开文件

从文件读取信息或向文件写入信息之前,必须先打开文件,用到open()函数,open()函数是fstream,ifstream,ofsteam对象的一个成员

open()函数的第一参数是要打开的文件的名称,第二个参数是模式:open(path,mode);

模式标志 描述
ios::app 追加模式。所有写入都追加到文件末尾。
ios::ate 文件打开后定位到文件末尾。
ios::in 打开文件用于读取。
ios::out 打开文件用于写入。
ios::trunc 如果该文件已经存在,则先删除该文件,再重新创建
ios::binary 二进制方式

且可以把多个模式结合起来用,如:

ofstream outfile;
outfile.open("data.dat",ios::out|ios::trunc);

就是以写入模式打开文件,且如果文件已经存在,就把之前的内容截断

关闭文件

虽然程序终止时,会自动关闭刷新所有的流,释放所有分配的内存,并关闭所有打开的文件,但最好还是在程序终止前用close()函数关闭文件

void close();

读写文件流

fstream也有类似cout,cin的流操作,ofstream<<str;一个ofstream对象可以和<<连接使用,将后面的内容写入ofstream对象打开的文件

如:

#include<iostream>
#include<fstream>
using namespace std;
int main(){
    ofstream outfile("data.dat");
    int a=4321;
    outfile<<a<<"test";

}

同样,ifstream对象可以和>>连用,将ifstream对象打开的文件的内容读到变量中。如:

#include<iostream>
#include<fstream>
using namespace std;
int main(){
    ifstream infile("data.dat");
    string str;
    infile>>str;
    cout<<str;

}

逐行和逐个字符读文件

逐个字符
#include<iostream>
#include<fstream>
using namespace std;
int main(){
    fstream file;
    char c;
    file.open("data.dat",ios::in);
    while(!file.eof()){
        file>>c;
        cout<<c;
    }
    file.close();
    cout<<endl;
}

file.eof()是文件对象的成员,当读到文档的结尾时,会返回一个EOF标志,eof()函数当遇到EOF标志时,返回boolean的true

逐行读取

需要用到getline()函数:getline(char* str,int size,char delim);

str:用来接收读文件流的字符串变量

size:字符数

delim:分隔符,一般为'\n'

#include<iostream>
#include<fstream>
using namespace std;
int main(){
    fstream file;
    char buffer[256];
    file.open("data.dat",ios::in);
    while(!file.eof()){
        file.getline(buffer,256,'\n');
        cout<<buffer<<endl;
    }
    file.close();
    cout<<endl;
}

流指针

ifstream 对象有一个get pointer指针,指向下一个被读取的元素

ofstream有一个put pointer指针,指向写入下一个元素的位置

fstream,同时继承了get和put指针

  • 获取流指针的位置

tellg()和tellp(),返回一个整数,表示当前的get和put指针的位置

  • 设置流指针的位置

seekg()和seekp(),他们有两种函数原型:

seekg(pos_type position);只有一个参数时,定义到第position的位置

seekg(off_type offset,seekdir direction)有两个参数时,用偏移量定位,direction是定位的初位置,offset是前后偏移量

参数 含义
ios::beg 从流开始位置计算的位移
ios::cur 从流指针当前位置开始计算的位移
ios::end 从流末尾处开始计算的位移

如:

file.seekg(-10,ios::cur)

就是从当前位置向前移动10个字节

例子:

#include<iostream>
#include<fstream>
using namespace std;
int main(){
    fstream file;
    file.open("data.dat",ios::in|ios::out);
    char buffer[100];
    file<<"Hello,tom";

    file>>buffer;
    file.close();
    cout<<buffer;
}

对文件先写后读,输出:

因为写完指针移动到了末尾,然后读就什么都读不出来,需要移动get指针

#include<iostream>
#include<fstream>
using namespace std;
int main(){
    fstream file;
    file.open("data.dat",ios::in|ios::out);
    char buffer[100];
    file<<"Hello,tom";
    file.seekg(0);
    file>>buffer;
    file.close();
    cout<<buffer;
}

二进制读写

二进制数据的读写用的是write和read函数:

write/read(char* buffer,streamsize size);

如:

#include<iostream>
#include<fstream>
using namespace std;
int main(){
    fstream file;
    file.open("data.dat",ios::in|ios::out|ios::binary);
    char buffer[100];
    file.write("Hello,eva",9);
    file.seekg(0);
    file.read(buffer,9);
    file.close();
    cout<<buffer;
}