c++文件操作

c++文件操作

一、文件打开选项设置
ios::in    = 0x01, //供读,文件不存在则创建(ifstream默认的打开方 式)
ios::out    = 0x02, //供写,文件不存在则创 建,若文件已存在则清空原内容(ofstream默认的打开方式)
ios::ate    = 0x04, //文件打开时,指针在文件最后。可改变指针的位置,常和in、out联合使用
ios::app    = 0x08, //供写,文件不存在则创建,若文件已存在则在原文件内容后写入 新的内容,指针位置总在最后
ios::trunc   = 0x10, // 在读写前先将文件长度截断为0(默认)
ios::nocreate = 0x20, //文件不存在时产生错误,常和in或app联合使用
ios::noreplace = 0x40, //文件存在时产生错误,常和out联合使用
ios::binary  = 0x80  //二进制格式文件
二、fstream库主要包括以下几个类:
  1. std::ifstream:用于从文件读取数据的输入文件流类。
  2. std::ofstream:用于向文件写入数据的输出文件流类。
  3. std::fstream:用于同时进行文件的读取和写入操作的输入/输出文件流类。

注意事项

若字符串使用了string定义,请在打开时将其转化为const char*类型,这是因为在C语言中并没有string类型,所有IO均采用char类型,建议定义字符串时使用char

以下是 fstream 的一些使用方法
打开文件:
  • ifstream file(“filename.txt”):创建一个ifstream对象并打开名为filename.txt的文件以进行读取。

  • ofstream file(“filename.txt”):创建一个ofstream对象并打开名为filename.txt的文件以进行写入。

  • fstream file(“filename.txt”):创建一个fstream对象并打开名为filename.txt的文件以进行读取和写入。

  • 你也可以使用先创建的形式,再通过open函数创建具体的文件 ,例如:

    #include<iostream>
    #include<fstream>
    using namespace std;
    
    int main()
    {
    	fstream IoFile;
    	IoFile.open("./a.bat",ios_base::out); //模式选择
    }
    
关闭文件:
  • file.close():关闭与文件流关联的文件。
检查文件是否打开成功:
  • file.is_open(),为true则打开成功,反之未成功。
从文件读取数据:
  • file>>variable:从文件流中读取数据并存储到变量中。
  • getline(file, line):从文件流中读取一整行数据并存储到line字符串中。
向文件写入数据:
  • file << data:将数据写入到文件流中。
检查文件流状态:
  • file.eof():检查文件流是否已到达文件末尾,true则是到达,反之。
  • file.fail():检查文件流是否发生错误,出现错误则返回true
  • file.good():检查文件流是否处于良好状态,发生错误则为true

演示代码:

#include<iostream>
#include<fstream>
using namespace std;

int main()
{
  fstream IoFile;
  IoFile.open("./a.bat",ios::out); //模式选择
  IoFile<<"张三"<< "  " << 76 << " " << 98 << " " << 67 << endl;
  IoFile << "李四"<< "  " << 89 << " " << 70 << " " << 60 << endl;
    IoFile << "王十"<< "  " << 91 << " " << 88 << " " << 77 << endl;
    IoFile << "黄二"<< "  " << 62 << " " << 81 << " " << 75 << endl;
    IoFile << "刘六"<< "  " << 90 << " " << 78 << " " << 67 << endl;
    IoFile.close(); //先写入
    IoFile.open("./a.bat",ios::in|ios::binary); //二进制读
    char name[10];
    int chinese,math,english;
    cout<< "姓名\t"
        << "英语\t"
        << "数学\t"
        << "英语\t"
        << "总分" << endl;
        // cout<<IoFile.is_open()<<endl;
     while(IoFile.is_open()&&!IoFile.eof()){
       IoFile>>name;
      IoFile>>chinese>>math>>english;
      cout << name << "\t" << chinese << "\t" << math << "\t" << english << "\t"
         << chinese + math + english<< endl;
         
     }
     IoFile.close();
     return 0;

}

使用ofsteamifstream的例题
#include<iostream>
#include<fstream>
using namespace std;

int main()
{
    char ch;
    ofstream out;
    out.open("./test.bat",ios::out|ios::binary);
    for(int i=0;i<90;i++)
    {
        if(i>0&&i%30==0){
            out.put('\n');
        }
        out.put(i);
        out.put(' ');
    }
    out.close();
    ifstream in("./test.bat",ios::in|ios::binary);
    cout<<"是否打开文件成功:"<<in.is_open()<<endl;
    while(in.get(ch))
    {
        cout<<ch;
    }
    in.close();
     return 0;
}
读写二进制文件:

首先你要注意我们不再使用插入和提取操作符(译者注:<< 和 >> 操作符). 你可以这么做,但它不会用二进制方式读写。你必须使用read() 和write() 方法读取和写入二进制文件,例如:

ofstream fout("file.dat", ios::binary); 

这会以二进制方式打开文件, 而不是默认的ASCII模式。

二进制写入:
fout.write((char *)(&number), sizeof(number)); 

二进制文件最好的地方是可以在一行把一个结构写入文件,用ASCII文件,你不得不每次一条的写入所有成员。例如:

struct OBJECT { 
    int number;
    char letter;
} obj; 
obj.number = 15;
obj.letter = ‘M’; 
fout.write((char *)(&obj), sizeof(obj)); 
文件读取:
ifstream fin("file.dat", ios::binary); 
fin.read((char *)(&obj), sizeof(obj));

这里不过多解释,他与文件写入基本相同。

读写文件的一些方法:

读时:

方法get() 每次返回一个字符。

方法ignore(int,char), 跳过一定数量的某个字符, 但你必须传给它两个参数。第一个是需要跳过的字符数。 第二个是一个字符, 当遇到的时候就会停止,例如:

fin.ignore(100, '\n'); 

跳过100个字符,或者不足100的时候,跳过所有之前的字符,包括 '\n'

写时:

put(char), 它每次向输出流中写入一个字符。

随机读写文件:

通过移动文件读写指针,可在文件指定位置进行读写,相关函数有:

  • seekg(绝对位置); //绝对移动 //输入流
  • seekg(相对位置,参照位置); //相对操作
  • tellg();// 返回当前指针位置 //输出流
  • seekp(绝对位置); //输出流
  • seekp(相对位置,参照位置);  //相对操作
  • tellp() //返回当前指针位置
参照位置:
  • ios::beg  = 0  //相对于文件头
  • ios::cur   = 1 //相对于当前位置
  • ios::end  = 2 //相对于文件尾

代码例如:

#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;

class Employee{
private:
    int number,age;
    char name[20];
    double salary;
public:
    Employee(){};
    Employee(int num,const char Name[],int Age,double Salary){
        number=num;
        strcpy(name,Name);
        age=Age;
        salary=Salary;
}
    void display(){
        
        cout<<number<<"\t"<<name<<"\t"<<age<<"\t"<<salary<<endl;
    }
};

int main()
{
    ofstream fout("./employee.bat",ios::out|ios::binary);
    Employee e1(1,"张三",30,2300);
    Employee e2(2,"李四",40,3000);
    Employee e3(3,"王五",50,4000);
    Employee e4(4,"刘六",60,5000);
    fout.write((const char *)&e1,sizeof(e1));
    fout.write((const char *)&e2,sizeof(e2));
    fout.write((const char *)&e3,sizeof(e3));
    fout.write((const char *)&e4,sizeof e4);
    //这里实现将e3年龄进行修改
    Employee e5(3,"王五",30,4000);
    fout.seekp(2*sizeof(e1),ios::beg);
    fout.write((const char *)&e5,sizeof(e5)); 
    fout.close();

    Employee e7;//读取一条王五的信息
    ifstream fin("./employee.bat",ios::in|ios::binary);
    fin.seekg(2*sizeof(e1),ios::beg);
    fin.read((char *)&e7,sizeof(e7));
    fin.close();
    e7.display();

    return 0;
}
文件复制:

方法一(逐个字符复制)

#include < fstream >
 
std::ifstream input("in",ios::binary);
std::ofstream output("out",ios::binary);
char ch;
 
while (input.get(ch)) output << ch;

方法二 (逐行复制)(注意使用这种方式input>>ch,他会默认跳过空白) 可以使用 input.unsetf(ios::skipws)

#include < fstream >
#include < string >
 
std::ifstream input("in",ios::binary);
std::ofstream output("out",ios::binary);
std::string line;
 
while (getline(input,line)) output << line << "\n";

方法三 (缓冲区复制) 最推荐使用并且效果极好

#include < fstream >
 
std::ifstream input("in",ios::binary);
std::ofstream output("out",ios::binary);
 
output << input.rdbuf();

方法四 (迭代器方法)

#include<fstream>
#include<iterator>
#include<algorithm>

istreambuf_iterator<char> begin_source(source);
istreambuf_iterator<char> end_source;
ostreambuf_iterator<char> begin_dest(destination); 
copy(begin_source, end_source, begin_dest);
    
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值