C++ 笔记2 文件读写

可以将顺序文件看作一个有限字符构成的顺序字符流,然后像对cin,cout一样的读写。回顾下输入输出流的层次结构。

目录

创建文件

#include<fstream> //包含头文件

方式1:定义ofstream,在构造函数中给出参数

ofstream outFile(“clients.dat”,ios::out|ios::binary); -clients..dat 要创建的文件的名字 -ios::out 文件打开方式 ios::out 输出到文件,删除原有内容 ios::app 输出到文件,保留原有内容,总是在尾部添加(app - append) -ios::binary 以二进制方式打开文件

方式2:创建ofstream对象,再用open函数打开

ofstream fout; //创建ofstream对象

fout.open(“test.out”,ios::out|ios::binary);

判断打开是否成功

if(!fout){ cout«“File open error!”«endl;

}

文件名可以给出绝对路径,也可以给出相对路径。没有交代路径信息,就是在当前文件夹下寻找。

  • 绝对路径

    ​ e.g. “c:\tmp\mydir\some.txt”

  • 相对路径

    • “\tmp\mydir\some.txt”

    当前盘符的根目录下的tmp\dir\some.txt

    • “tmp\mydir\some.txt”

      当前文件夹的tmp子文件夹里面的…

    • “..\ tmp\mydir\some.txt”

      当前文件夹的父文件夹下面的tmp子文件夹里面的…

    • “..\..\ tmp\mydir\some.txt”

    当前文件夹的父文件夹的父文件夹下面的tmp子文件夹里面的…

文件的读写指针

对于输入文件,有一个读指针;对于输出文件,有一个写指针;对于输入输出文件,有一个读写指针;指针的作用即为,标识文件操作的当前位置,该指针在哪里,读写操作就在哪里进行。

写操作

​ tellp()取得写指针位置 seekp(location)向指定位置写入

ofstream fout(“a1.out”,ios::app); //以添加方式打开

long location = fout.tellp(); //取得写指针的位置

location p = 10;

fout.seekp(location); //将写指针移动到底10个字节处

fout.seekp(location, ios::beg); //从头部数location个字节 (beg-begin)

fout.seekp(location, ios::cur); //从当前位置数location个字节 (cur-current)

fout.seekp(location, ios::end); //从尾部数location个字节 (这种情况下location<=0)

读操作

​ tellg()取得读指针位置 seekg(location)从指定位置读

ifstream fin(“a1.in”,ios::ate); //打开文件,定位文件指针到文件尾(ate-at end)

long location = fin.tellg(); //获取读指针的位置,从而可以获取文件长度

location = 10;

fin.seekg(location); //将头指针移动到低10个字节处

fin.seekg(location, ios::beg); //从头部数location个字节

fin.seekg(location, ios::cur); //从当前位置数location个字节

fin.seekg(location, ios::end); //从尾部数location个字节

显示关闭文件

ifstream fin(“test.dat”, ios::in);

fin.close();

ofstream fout(“test.dat”, ios::out);

fout.close();

文件读写

字符文件读写

​ 因为文件也是流,所以流的成员函数和流操作算子也同样适用于文件流。

e.g. 1.写一个程序,将文件in.txt里面的整数排顺后,输出到out.txt

#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    vector<int> v;
    ifstream srcFile("in.txt",ios::in);
    ofstream destFile("out.txt",ios::out);
    int x;
    while (srcFile >> x)
        v.push_back(x);
    sort(v.begin(),v.end());
    for(int i = 0; i < v.size(); i++)
        destFile<<v[i]<<" ";
    destFile.close();
    srcFile.close();
    return 0;
}

运行结果:

二进制文件读写

从文件读入内存

ifstream和fstream的成员函数:

istream& read (char* s, long n);

将文件读指针指向的地方的n个字节的内容,读入到内存地址s,然后将文件读指针向后移动n字节。

从内存写入文件

ofstream和fstream的成员函数:

istream& write(const char* s, long n);

将内存地址s处的n个字节内容,写入到文件中写指针指向的位置,然后将文件写指针向后移动n字节。

e.g. 1.从键盘输入几个学生的姓名的成绩,并以二进制文件形式保存

#include<iostream>
#include<fstream>
using namespace std;
struct Student{
    char name[20];
    int score;
};
int main()
{
    Student s;
    ofstream OutFile("students.dat",ios::out|ios::binary);
    while(cin>>s.name>>s.score)
        OutFile.write((char *) & s, sizeof(s) ); 
//(char *) & s表示取s的地址,并转为char*类型
    OutFile.close();
    return 0;
}

输入:

Tom 60

Jack 80

Peter 100

^Z + 回车

运行结果:

当前文件夹下生产student.dat文件,且为72字节(20B+4B)* 3 = 72B

使用记事本打开,呈现:

使用sublime text3打开,呈现:

会发现其以二进制形式存储, \(3C_{16}\)对应分数\(60_{10}\), \(50_{16}\)对应分数\(80_{10}\), \(64_{16}\)对应分数\(100_{10}\).

还可以发现,这里是以大端模式进行存储的。(即数据的高字节,在内存的低地址;数据的低字节,在内存的高地址)

e.g. 2.将student.dat文件的内容读出并显示出来.

#include<iostream>
#include<fstream>
using namespace std;
struct Student{
    char name[20];
    int score;
};
int main()
{
    Student s;
    ifstream inFile("students.dat",ios::in|ios::binary);
    if(!inFile){
        cout<<"Error."<<endl;
        return 0;
    }
    while(inFile.read((char* ) &s, sizeof(s) )){
        cout<<s.name<<" "<<s.score<<endl;
    }
    inFile.close();
    return 0;
}

运行结果:

转载请注明原地址,小黑特的博客:http://te-shi.com 谢谢!

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦