C++文件操作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++文件操作相关的知识,希望对你有一定的参考价值。

 

    ofstream fout;        创建一个对象
 
    fout.open("jar.txt");        打开一个文件
 
    ofstream fout("jar,txt");        等价于上面两步操作
 
    然后,以使用cout的方式使用fout(或其他名称)。例如 fout<<" Dull Data";
 
    ostream是ofstream的基类,既可以使用任何格式控制。
 
    ifstream fin;
 
    fin.open("Test.txt");
 
    ifstream fin("Test.txt");    与上面两步操作等价
 
    char ch;
 
    fin>>ch;        读取一个字母
 
    char buff[80];
 
    cin>>buff;        读取一个word
 
    fin.getline(buff,80);         从文件中读取一行
 
    string line;
 
    getline(fin,line);    从文件中读取一行
 
    fout.close();     显式的关闭文件
 
    fin.close()        显式的关闭文件
 
    控制台中可以用ctrl+z代替EOF
 
 
    逐词读取 空格隔开
    ifstream fin("data.txt"); 
    string s; 
    while( fin >> s )
    {   
        cout << "Read from file: " << s << endl; 
    }
 
 
    逐行读取 回车换行隔开 
 
    方式一:                //读取到string对象 不用指定长度
    ifstream fin("data.txt"); 
    string s; 
    while( getline(fin,s) )
    {   
        cout << "Read from file: " << s << endl;
    }
 
 
 
    方式二:                //读取到字符数组 指定长度
    ifstream fin("data.txt");
    const int LINE_LENGTH = 100;
    char str[LINE_LENGTH]; 
    while( fin.getline(str,LINE_LENGTH) )
    {   
        cout << "Read from file: " << str << endl;
    }
 
 
    getline()函数详解
    getline()的原型是istream& getline ( istream &is , string &str , char delim );
    从一个流中读取一串字符放到指定位置,读取时遇到delim停止(默认为\n);
 
    例程:
    #include<fstream>
    #include<iostream>
    #include<string>
    using namespace std;
    int main()
    {
        string filename;
        cout << "Enter name for new file:";
        cin >> filename;
        ofstream fout(filename.c_str());
        fout << "For your eyes only!\n";
        cout << "Enter your secret number:";
        float secret;
        cin >> secret;
        fout << "Your secret number is " << secret << endl;
        fout.close();
        ifstream fin(filename.c_str());
        cout << "Here are the contents of " << filename << ":\n";
        char ch;
        while (fin.get(ch))
        {
            cout << ch;
        }
        cout << "Done!\n";
        fin.close();
        return 0;
    }
 
    检测文件是否成功打开。
    fin.open(argv[file]);
    if(fin.fail())
    {
        ......
    }
    或者
    if(!fin)
    {
        ......
    }
    或者
    if(!fin.is_open())
    {
        ......
    }
    或者
    if(!fin.good())
    {
        ......
    }
 
    依次打开多个文件
 
    ifstream fin;
    fin.open("test.txt");
    ...
    fin.close();
    fin.clear();
    fin.open("test.txt");
    ...
    fin.close();
 
    文件打开模式选择
 
    #include<fstream>
    #include<iostream>
    #include<string>
    #include<stdlib.h>
    using namespace std;
    const char* file = "guests.txt";
    int main()
    {
        char ch;
        ifstream fin;
        fin.open(file);
 
        if (fin.is_open())
        {
            cout << "Here are the current contents of the" << file << "fiel:\n";
            while (fin.get(ch))
            {
                cout << ch;
            }
            fin.close();
        }
 
        ofstream fout(file, ios::out | ios::app);
        if (!fout.is_open())
        {
            cerr << "Can‘t open" << file << "file for out put.\n";
            exit(EXIT_FAILURE);
        }
        cout << "Enter guest names (enter a blank line to quit):\n";
        string name;
        while (getline(cin,name)&&name.size()>0)
        {
            fout << name << endl;
        }
        fout.close();
 
        fin.clear();
        fin.open(file);
        if (fin.is_open())
        {
            cout << "Here are the new contents of the " << file << "file:\n";
            while (fin.get(ch))
            {
                cout << ch;
            }
            fin.close();
        }
        cout << "Done!\n";
        return 0;
    }
 
    文本形式和二进制形式保存
 
    const int LIM = 20;
    struct planet
    {
        char name[LIM];
        double population;
        double g;
    }
    planet pl;
 
    保存方式一:
 
    ofstream fout("planet.dat",ios_base::out|ios_base::app);
    fout<<pl.name<<" "<<pl.population<<" "<<pl.g<<"\n";
 
    保存方式二:
 
    ofstream fout("planet.dat",ios_base::out|ios_base::app|ios_base::binary);
    fout.write((char*)&pl,sizeof pl);
 
    采用二进制文件模式时:速度快,不丢失数据,不发生隐含转换。
    采用文本模式时:会发生隐式转换,可能丢失数据。在不同的系统上转换结果可能不一样。
 
    采用write()函数的时候,第一个参数是地址,第二个参数是字节。地址必须转换为char*类型
    read()和write()的功能是相反的,可以用read()来恢复write()写入的数据。
 
    案例:
        #include<iostream>
        #include<fstream>
        #include<iomanip>
        #include<stdlib.h>
        using namespace std;
        inline void eatline() { while (std::cin.get() != ‘\n‘)continue; }
        struct planet
        {
            char name[20];
            double population;
            double g;
        };
        const char* file = "planets.dat";
        int main()
        {
            planet pl;
            cout << fixed << right;
            ifstream fin;
            fin.open(file, ios_base::in | ios_base::binary);
            if (fin.is_open())
            {
                cout << "Here are the current contents of the " << file << "file:\n";
                while (fin.read((char*)&pl,sizeof pl))
                {
                    cout << setw(20) << pl.name << ": "
                        << setprecision(0) << setw(12) << pl.population
                        << setprecision(2) << setw(6) << pl.g << endl;
                }
                fin.close();
            }
            ofstream fout(file, ios_base::out | ios_base::app | ios_base::binary);
            if (!fout.is_open())
            {
                cerr << "Can‘t Open " << file << "fiel for output:\n";
                exit(EXIT_FAILURE);
            }
            cout << "Enter plant name(Enter a blank line to quit):\n";
            cin.get(pl.name, 20);
            while (pl.name[0]!=‘\0‘)
            {
                eatline();
                cout << "Enter planetary population:";
                cin >> pl.population;
                cout << "Enter planet‘s acceleration of gravity:";
                cin >> pl.g;
                eatline();
                fout.write((char *)&pl, sizeof pl);
                cout << "Enter planet name (Enter a blank line to quit):\n";
                cin.get(pl.name, 20);
            }
            fout.close();
 
            fin.clear();
            fin.open(file, ios_base::in | ios_base::binary);
            if (fin.is_open())
            {
                cout << "Here are the new contents of the " << file << "file:\n";
                while (fin.read((char*)&pl,sizeof pl))
                {
                    cout << setw(20) << pl.name << ": "
                        << setprecision(0) << setw(12) << pl.population
                        << setprecision(2) << setw(6) << pl.g << endl;
                }
                fin.close();
            }
            cout << "Done!\n";
        }
 
        打开文件用于读写:
            fstream finout;
            finout.Open(file,ios::in|ios::out|ios::binary);
        打开文件,移动到文件开头并显示文件内容。
            int ct=0;
            if(finout.is_open())
            {
                finout,seekg(0);
                cout<<"Here are the current contents of the "
                    <<file<<"file:\n";
                while(finout.read((char*)&pl,sizeof pl))
                {
                    cout<<ct++<<": "<<setw(LIM)<<pl.population
                        <<setprecision(0)<<setw(12)<<pl.population
                        <<setprecision(2)<<setw(6)<<pl.g<<endl:
                }
                if(finout.eof())
                {
                    finout.clear();
                }
                else
                {
                    cerr<<"Error in reading "<<file<<".\n";
                    exit(EXIT_FAILURE);
                }
 
            }
            else
            {
                cerr<<file<<" could ont be opened---bye.\n";
                exit(EXIT_FAILURE);
            }
        选择修改记录:
            cout<<"Enter the record number you wish to change: ";
            long rec;
            cin>>rec;
            eatline()
            if(rec<0||rec>=ct)
            {
                cerr<<"Invalid record bumber --bye \n";
                exit(EXIT_FAILURE);
 
            }
            streampos place=rec * sizeof pl;
            finout.seekg(place);
            ct 表示记录号。如果试图超过文件尾,程序将退出。
            接下来显示当前记录:
 
            finout.read((char *)&pl,sizeof pl);
            cout<<"Your selection:\n";
            cout<<rec<<": "<<setw(LIM)<<pl.name<<": "
                <<setprecision(0)<<setw(12)<<pl.population
                <<setprecision(2)<<setw(6)<<pl.g<<endl;
            if(finout.eof())
            {
                finout.clear();
            }
            显示记录之后,现在可以执行修改记录。
 
            cout<<"Enter planet name: ";
            cin.get(pl.name,LIM);
            eatline();
            cout<<"Enter planetary population: ";
            cin>>pl.population;
            cout<<"Enter planet‘s acceleration of gravity: ";
            cin>>pl.g;
            finout.seekp(place);
            finout.write((char*)&pl,sizeof pl)<<flush;
 
            if(finout.fail())
            {
                cerr<<"Error on attempted write\n";
                exit(EXIT_FAILURE);
            }
    总结案例:
        #include<iostream>
        #include<fstream>
        #include<iomanip>
        #include<stdlib.h>
        using namespace std;
        const int LIM = 20;
        struct planet
        {
            char name[LIM];
            double population;
            double g;
        };
        const char* file = "Planet.dat";
        inline void eatline() { while (cin.get() != ‘\n‘)continue; }
        int main()
        {
            planet pl;
            cout << fixed;
            fstream finout;
            finout.open(file, ios_base::in | ios_base::out | ios_base::binary);
            int ct = 0;
            if (finout.is_open())
            {
                finout.seekg(0);
                cout << "Here are the current contents of the " << file << "file:\n";
                while (finout.read((char *)&pl,sizeof pl))
                {
                    cout << ct++ << ": " << setw(LIM) << pl.name << ": "
                        << setprecision(0) << setw(12) << pl.population
                        << setprecision(2) << setw(6) << pl.g << endl;
 
                }
                if (finout.eof())
                {
                    finout.clear();
                }
                else
                {
                    cerr << "Error in reading" << file << ".\n";
                    exit(EXIT_FAILURE);
                }
            }
            else
            {
                cerr << file << "could not be opened--bye.\n";
                exit(EXIT_FAILURE);
            }
 
            cout << "Enter the record number you wish to change: ";
            long rec;
            cin >> rec;
            eatline();
            if (rec<0 || rec >= ct)
            {
                cerr << "Invalid record bumber --bye \n";
                exit(EXIT_FAILURE);
 
            }
            streampos place = rec * sizeof pl;
            finout.seekg(place);
            if (finout.fail())
            {
                cerr << "Error on attempted seek\n";
                exit(EXIT_FAILURE);
            }
 
            finout.read((char *)&pl, sizeof pl);
            cout << "Your selection:\n";
            cout << rec << ": " << setw(LIM) << pl.name << ": "
                << setprecision(0) << setw(12) << pl.population
                << setprecision(2) << setw(6) << pl.g << endl;
            if (finout.eof())
            {
                finout.clear();
            }
 
            cout << "Enter planet name: ";
            cin.get(pl.name, LIM);
            eatline();
            cout << "Enter planetary population: ";
            cin >> pl.population;
            cout << "Enter planet‘s acceleration of gravity: ";
            cin >> pl.g;
            finout.seekp(place);
            finout.write((char*)&pl, sizeof pl) << flush;
 
            if (finout.fail())
            {
                cerr << "Error on attempted write\n";
                exit(EXIT_FAILURE);
            }
            ct = 0;
            finout.seekg(0);
            cout << "Here are the new contents of the " << file << " file:\n";
            while (finout.read((char *)&pl,sizeof pl))
            {
                cout << ct++ << ":" << setw(LIM) << pl.name << ": "
                    << setprecision(0) << setw(12) << pl.population
                    << setprecision(2) << setw(6) << pl.g << endl;
            }
            cout << "Done!\n";
            return 0;
        }
 
 
    临时文件:
        #include<iostream>
        #include<stdlib.h>
        using namespace std;
        int main()
        {
 
            cout << "This system can generate up to " << TMP_MAX
                << " temporary names of up to " << L_tmpnam
                << " characters.\n";
            char pasName[ L_tmpnam ] = { ‘\0‘ };
            cout << "Here are ten names:\n";
            for (int i = 0;i < 10;i++)
            {
                tmpnam(pasName);
                cout << pasName <<endl;
            }
            return 0;
        }    
    上面代码可以生成10个零时文件名。    
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

以上是关于C++文件操作的主要内容,如果未能解决你的问题,请参考以下文章

C++ 文件的简单操作

浅谈C++的文件操作(上)

c++ 文件操作详解

C++核心编程文件操作

C++文件操作

C++:文件操作 | 读写文本文件