• C++ 笔记2

    05-03-19

    C++ 笔记2 文件读写

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

    1556815037308328.png






    (一)、创建文件

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

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

    ofstream outFile(“clients.dat”,ios::out|ios::binary);

    -clients..dat         要创建的文件的名字

    -ios::out               文件打开方式

           ios::out         输出到文件,删除原有内容

           ios::app        输出到文件,保留原有内容,总是在尾部添加(app - append

    -ios::binary          以二进制方式打开文件

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

    ofstream fout; //创建ofstream对象

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

    判断打开是否成功

    if(!fout){
           cout<<”File open error!”<<endl;
    }

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

    l  绝对路径

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

    l  相对路径

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

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

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

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

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

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

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

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

     

    (二)、文件的读写指针

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

    l  写操作

    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个字节 (这种情况下location0)

    l  读操作

    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个字节

    l  显示关闭文件

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

    fin.close();

     

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

    fout.close();


    (三)、文件读写

    1.字符文件读写

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

    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;
    }

    运行结果:

    1556815273454791.png






    1556815226116977.png





    2.二进制文件读写

    a.从文件读入内存

    ifstreamfstream的成员函数:

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

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

    b.从内存写入文件

    ofstreamfstream的成员函数:

    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 + 回车

    运行结果:

    1556815368897534.png





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

    1556815412538921.png





    使用记事本打开,呈现:

    1556815432125292.png




    使用sublime text3打开,呈现:

    1556815452575721.png









    会发现其以二进制形式存储,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;
    }

    运行结果:
    1556815574228819.png

    更多

请写一条留言给我们