zoukankan      html  css  js  c++  java
  • C++文件读写

    本文主要用于探讨使用C++来进行文件读写操作。

    在C++中,所有的输入输出操作大部分都继承自 ios_base 基类,详细的继承体系如下图所示

    fstream的使用

    在fstream类中,成员函数open()实现打开文件的操作,从而将数据流和文件进行关联,通过ofstream,ifstream,fstream对象进行对文件的读写操作,同时在打开文件时,可以指定打开的模式,如读、写或者读写,可选模式如下

    mode detail
    ios::in 为输入(读)而打开文件
    ios::out 为输出(写)而打开文件
    ios::ate 初始位置:文件尾
    ios::app 所有输出附加在文件末尾
    ios::trunc 如果文件已存在则先删除该文件
    ios::binary 二进制方式

    open的定义方式

    void open(const wchar_t *_Filename, 
        ios_base::openmode mode= ios_base::in | ios_base::out;
    
    void open(const wchar_t *_Filename, 
        ios_base::openmode mode= ios_base::in | ios_base::out, 
        int prot = ios_base::_Openprot);
    

    其中,filename表示操作文件名,mode表示打开文件的方式,prot表示打开文件的属性。在打开文件时,在stream类的构造函数中调用open()函数都有自己默认的操作方式

    ofstream out("...", ios::out);  
    ifstream in("...", ios::in);  
    fstream foi("...", ios::in|ios::out); 
    

    使用write()read()函数进行文件读写

    int main(){
        string file_path = "test.txt";
        char info[] = "hello fan";
        char buffer[256];
        ofstream out(file_path, ios::binary);
        if(out.is_open()){
            out.write(info, sizeof(info));
            out.close();
        }
        ifstream in(file_path, ios::binary);
        if(in.is_open()){
            while(!in.eof()){
                in.read(buffer, 100);
                cout << buffer << endl;
            }
            in.close();
        }
    
        return 0;
    }
    // out
    /*
    hello fan
    */
    

    ofstream重载了 <<操作符可用来向文件输出数据,ifstream重载了>>操作符,可用来读入数据。

    #include <iostream>
    #include<fstream>
    #include<string>
    
    using namespace std;
    
    int main(){
        string file_path = "test.txt";
        char buffer[256];
        ofstream out(file_path);
        if(out.is_open()){
            out << "hello ";
            out << "fan";
            out.close();
        }
        ifstream in(file_path);
        if(in.is_open()){
            while(!in.eof()){
                in.getline(buffer, 100);
                cout << buffer << endl;
            }
    
        }
        return 0;
    }
    // hello fan
    

    在上述代码中,使用is_open()函数,用来判断文件是否正常打开,eof()函数用来判断是否读到文件末尾。

    除了这些以外,还有一些验证流的状态的成员函数(所有都返回bool型返回值):

    • bad()
      如果在读写过程中出错,返回 true 。例如:当我们要对一个不是打开为写状态的文件进行写入时,或者我们要写入的设备没有剩余空间的时候。

    • fail()
      除了与bad() 同样的情况下会返回 true 以外,加上格式错误时也返回true ,例如当想要读入一个整数,而获得了一个字母的时候。

    • good()
      这是最通用的:如果调用以上任何一个函数返回true 的话,此函数返回 false 。

    为了能够更为方便地对文件进行操作,还需要能够判断我们读文件读到了哪里,使用函数tellg/tellp 用于提取当前文件指针的位置,使用函数 seekg/seekp 来将文件指针移到某处

    • tellg() 和 tellp()
      这两个成员函数不用传入参数,返回pos_type 类型的值(根据ANSI-C++ 标准) ,就是一个整数,代表当前get 流指针的位置 (用tellg) 或 put 流指针的位置(用tellp).

    • seekg() 和seekp()
      这对函数分别用来改变流指针get 和put的位置。两个函数都被重载为两种不同的原型:

    seekg ( pos_type position ); 
    seekp ( pos_type position );
    

    使用这个原型,流指针被改变为指向从文件开始计算的一个绝对位置。要求传入的参数类型与函数 tellg 和tellp 的返回值类型相同。

    seekg ( off_type offset, seekdir direction ); 
    seekp ( off_type offset, seekdir direction );
    

    使用这个原型可以指定由参数direction决定的一个具体的指针开始计算的一个位移(offset)。它可以是:

    type detail
    ios::beg 从流开始位置计算的位移
    ios::cur 从流指针当前位置开始计算的位移
    ios::end 从流末尾处开始计算的位移

    示例

    int main(){
        string file_path = "test.txt";
        char buffer[256];
        ifstream in(file_path);
        if(in.is_open()){
            auto site = in.tellg();
            in.seekg(site+6, ios::cur);
            while(!in.eof()){
                in.getline(buffer, 100);
                cout << buffer << endl;
            }
    
        }
        return 0;
    }
    

    上述文件中数据为 "hello fan",输出为 "fan",因为开始时,文件指针指向文件开头,使用tellg()函数获取文件指针位置,然后使用seekg()函数将文件指针后移6个字符,因此读取结果为 "fan"。

    简单文件读写示例

    #include <iostream>
    #include<fstream>
    #include<string>
    
    using namespace std;
    
    int choose_mod(){
        int f = 0;
        cout << "----Easy file read and write----" << endl;
        cout << "Please choose write or read file" << endl;
        cout << "Enter 1, read file" << endl;
        cout << "Enter 2, write file" << endl;
        cout << "Enter 3, exit" << endl;
        cout << "--------------------------------" << endl;
        cin >> f;
        while(f != 1 && f != 2 && f != 3){
            cout << "Please choose 1 or 2 or 3" << endl;
            cin >> f;
        }
    
    }
    
    int main(){
        string file_name = "test.txt";
        int mod = choose_mod();
        char buffer[256];
        ifstream in;
        ofstream out;
        string tmp;
    
        while(mod != 3){
            if(mod == 1){
                in.open(file_name);
                if(in.is_open()){
                    while(!in.eof()){
                        in.getline(buffer, 100);
                        cout << buffer << endl;
                    }
                    in.close();
                }
            }else{
                out.open(file_name, ios::app);
                if(out.is_open()){
                    cout << "Please enter string, Enter quit end" << endl;
                    tmp = "";
                    while(true){
                        getline(cin, tmp);
                        if(tmp == "quit") break;
                        out << tmp << "
    ";
                    }
                    out.close();
                }
            }
            mod = choose_mod();
        }
        cout << "Quit" << endl;
    
        return 0;
    }
    

    参考文献

    C++文件读写详解
    C++文件读写操作总结

  • 相关阅读:
    bzoj 3438 小M的作物
    洛谷 1126 机器人搬重物
    hdu 4055 Number String
    顺序对齐
    codevs 1300 文件排版
    NOIP 2015 提高组 Day2
    poj 2484 A Funny Game
    51nod 1548 欧姆诺姆和糖果 (制约关系优化枚举)
    hdu 1907 John (anti—Nim)
    hdu 2516 取石子游戏 (斐波那契博弈)
  • 原文地址:https://www.cnblogs.com/zhhfan/p/14800701.html
Copyright © 2011-2022 走看看