ofstream的使用方法
ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间; 
在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符: 
1、插入器(<<) 
  向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<’\n’;就表示把字符串"Write Stdout"和换行字符(’\n’)输出到标准输出流。 
2、析取器(>>) 
  从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。 
  在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。 
一、打开文件 
  在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是: 
void open(const char* filename,int mode,int access); 
参数: 
filename:  要打开的文件名 
mode:    要打开文件的方式 
access:   打开文件的属性 
打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下: 
ios::app:   以追加的方式打开文件 
ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性 
ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文 
ios::in:    文件以输入方式打开(文件数据输入到内存) 
ios::out:   文件以输出方式打开(内存数据输出到文件) 
ios::nocreate: 不建立文件,所以文件不存在时打开失败 
ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败 
ios::trunc:  如果文件存在,把文件长度设为0 
  可以用“或”把以上属性连接起来,如ios::out|ios::binary 
  打开文件的属性取值是: 
0:普通文件,打开访问 
1:只读文件 
2:隐含文件 
4:系统文件 
  可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。 
  例如:以二进制输入方式打开文件c:\config.sys 
fstream file1; 
file1.open("c:\\config.sys",ios::binary|ios::in,0); 
  如果open函数只有文件名一个参数,则是以读/写普通文件打开,即: 
file1.open("c:\\config.sys"); <=> file1.open("c:\\config.sys",ios::in|ios::out,0); 
  另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了: 
fstream file1("c:\\config.sys"); 
  特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。ifstream file2("c:\\pdos.def");//以输入方式打开文件 
ofstream file3("c:\\x.123");//以输出方式打开文件 
  所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定

二、关闭文件 
  打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。 
三、读写文件 
  读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式 
  1、文本文件的读写 
  文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下: 
  file2<<"I Love You";//向文件写入字符串"I Love You" 
  int i; 
  file1>>i;//从文件输入一个整数值。 
  这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些 
操纵符 功能 输入/输出 
dec 格式化为十进制数值数据 输入和输出 
endl 输出一个换行符并刷新此流 输出 
ends 输出一个空字符 输出 
hex 格式化为十六进制数值数据 输入和输出 
oct 格式化为八进制数值数据 输入和输出 
setpxecision(int p) 设置浮点数的精度位数 输出 
  比如要把123当作十六进制输出:file1<要把3.1415926以5位精度输出:file1<。 
  2、二进制文件的读写 
①put() 
  put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put(’c’);就是向流写一个字符’c’。 
②get() 
  get()函数比较灵活,有3种常用的重载形式: 
  一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。 
  另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。 
  还有一种形式的原型是:ifstream &get(char *buf,int num,char delim=’\n’);这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符’\n’。例如: 
  file2.get(str1,127,’A’); //从文件中读取字符到字符串str1,当遇到字符’A’或读取了127个字符时终止。 
③读写数据块 
  要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:read(unsigned char *buf,int num); 
    write(const unsigned char *buf,int num); 
  read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。 
例: 
    unsigned char str1[]="I Love You"; 
int n[5]; 
    ifstream in("xxx.xxx"); 
    ofstream out("yyy.yyy"); 
    out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中 
    in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换 
    in.close();out.close(); 
四、检测EOF 
  成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof(); 
例:  if(in.eof()) ShowMessage("已经到达文件尾!"); 
五、文件定位 
  和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是seekg()和seekp()。seekg()是设置读位置,seekp是设置写位置。它们最通用的形式如下: 
    istream &seekg(streamoff offset,seek_dir origin); 
    ostream &seekp(streamoff offset,seek_dir origin); 
  streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举: 
ios::beg:  文件开头 
ios::cur:  文件当前位置 
ios::end:  文件结尾 
  这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。例: 
   file1.seekg(1234,ios::cur); //把文件的读指针从当前位置向后移1234个字节 
   file2.seekp(1234,ios::beg); //把文件的写指针从文件开头向后移1234个字节 
fstream的用法 
   
开一个文件 
fstream f; 
f.open("1.txt", ios::in | ios::binary); 
if (!f.is_open()) // 检查文件是否成功打开 
    cout << "cannot open file." << endl; 
ios::in与ios::bianry均为int型,定义文件打开的方式。 
ios::in -- 打开文件用于读。 
ios::out -- 打开文件用于写,如果文件不存在,则新建一个;存在则清空其内容。 
ios::binary -- 以二进制bit流方式进行读写,默认是ios::text,但最好指定这种读写方式,即使要读写的是文本。因为在ios::text模式下,在写入时’\ n’字符将转换成两个字符:回车+换行(HEX: 0D 0A) 写入,读入时作逆转换,这容易引起不必要的麻烦。ios::app -- 打开文件在文件尾进行写入,即使使用了seekp改变了写入位置,仍将在文件尾写入。 
ios::ate -- 打开文件在文件尾进行写入,但seekp有效。 
读写位置的改变 
f.seekg(0, ios::beg); // 改变读入位置 g mean Get 
f.seekp(0, ios::end); // 改变写入位置 p mean Put 
第一个参数是偏移量offset(long),第二个参数是offset相对的位置,三个值: 
ios::beg -- 文件头    ios::end -- 文件尾    ios::cur -- 当前位置

文件读写 
char s[50]; 
f.read(s, 49); 
s[50] = ’\0’; // 注意要自己加上字符串结束符 
char *s = "hello"; 
f.write(s, strlen(s)); 
补充    记得读写完成后用f.close()关闭文件。 
例子    下面的程序用于删除带有行号的源程序中的行号。 
#include  
#include  
using namespace std; 
//定义要删除的行号格式,下面定义的是型如: #0001 的行号 
const int LINE_NUM_LENGTH = 5; 
const char LINE_NUM_START = ’#’; 
int main(int argc, char *argv[]) 
{ 
fstream f; 
char *s = NULL; 
int n; 
for (int i = 1; i < argc; i++) { 
    cout << "Processing file " << argv[i] << "......"; 
    f.open(argv[i], ios::in | ios::binary); 
    if (!f.is_open()){ 
        cout << "CANNOT OPEN"<< endl; 
        continue; 
    } 
    f.seekg(0, ios::end); 
    n = f.tellg(); // 文件大小 
    s = new char[n+1]; 
    f.seekg(0, ios::beg); 
    f.read(s, n); 
    s[n] = ’\0’; 
    f.close(); 
    // 采用一种简单的判断,遇到LINE_NUM_START后接一个数字, 
    // 则认为它是一个行号. 
    for (int j = 0; j < n; j++) { 
        if (s[j] == LINE_NUM_START &&            (s[j+1] >= ’0’ && s[j+1] <= ’9’)) { 
            for (int k = j; k < j + LINE_NUM_LENGTH; k++) 
                s[k] = ’ ’; 
        } 
    } 
    f.open(argv[i], ios::out | ios::binary); 
    if (!f.is_open()) { 
        cout << "CANNOT OPEN" << endl; 
        delete[] s; 
        continue; 
    } 
    f.write(s, n); 
    f.close(); 
    cout << "OK" << endl; 
    delete[] s; 
} 
return 0; 
}

ofstream的使用方法--超级精细。C++文件写入、读出函数(转)的更多相关文章

  1. Java学习-015-CSV 文件写入实例源代码

    在日常的自动化测试脚本编写的过程中,有时要将获取的测试结果或者测试数据存放在数据文件中,以用作后续的参数化测试.常用的文件文件类型无非 txt.csv.xls.properties.xml 这五种文件 ...

  2. PHP文件读写操作之文件写入代码

    在PHP网站开发中,存储数据通常有两种方式,一种以文本文件方式存储,比如txt文件,一种是以数据库方式存储,比如Mysql,相对于数据库存储,文件存储并没有什么优势,但是文件读写操作在基本的PHP开发 ...

  3. C++文件写入,读出函数ofstream,ifstream的使用方法

    ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间. 1.插入器(<<)  向流输出数据.比如说系统有一个默认的标准输出流(cout),一般情况下 ...

  4. 文件操作ofstream,open,close,ifstream,fin,依照行来读取数据, fstream,iosin iosout,fio.seekg(),文件写入和文件读写,文件拷贝和文件

     1.ofstream,open,close 写入文件 #include<iostream> #include<fstream> using namespace std; ...

  5. ofstream的使用方法

    ofstream的使用方法ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间;  在C 中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包 ...

  6. 两种方法上传本地文件到github

    https://www.jianshu.com/p/c70ca3a02087 自从使用github以来,一直都是在github网站在线上传文件到仓库中,但是有时因为网络或者电脑的原因上传失败.最重要的 ...

  7. 两种方法上传本地文件到github(转)

    自从使用github以来,一直都是在github网站在线上传文件到仓库中,但是有时因为网络或者电脑的原因上传失败.最重要的原因是我习惯本地编辑,完成以后再一起上传github.看过了几个教程,总结出最 ...

  8. 两个Map的对比,三种方法,将对比结果写入文件。

    三种方法的思维都是遍历一个map的Key,然后2个Map分别取这2个Key值所得到的Value. #第一种用entry private void compareMap(Map<String, S ...

  9. Dom方法,解析XML文件

    Dom方法,解析XML文件的基本操作 package com.demo.xml.jaxp; import java.io.IOException; import javax.xml.parsers.D ...

随机推荐

  1. 在mysql中使用group by和order by取每个分组中日期最大一行数据

    转载自:https://blog.csdn.net/shiyong1949/article/details/78482737 在mysql中使用group by进行分组后取某一列的最大值,我们可以直接 ...

  2. iOS9UICollectionView自定义布局modifying attributes returned by UICollectionViewFlowLayout without copying them

    UICollectionViewFlowLayout has cached frame mismatch This is likely occurring because the flow layou ...

  3. Linux学习笔记05—文件与目录权限

    1. 绝对路径与相对路径绝对路径:路径的写法一定由根目录 ‘/’写起,例如 /usr/local/mysql 这就是绝对路径相对路径:路径的写法不是由根目录 ‘/’写起,例如:首先用户进入到/, 然后 ...

  4. centos7 做rails 执行rails server 报错

    做操作rails   server 时  报错 这个错误时因为一些东西没有安装 gem install execjsgem install therubyracersudo apt-get insta ...

  5. CentOS 7使用yum安装Docker

    安装依赖 # 配置阿里云源 # 备份 cp /etc/yum.repos.d/CentOS-Base.repo{,.bak'_'`date +%Y%m%d_%H%M%S`} # 下载 wget -O ...

  6. IAR EWAR 内联汇编 调用外部函数 Error[Og005], Error[Og006]

    How do I call a C function in another module from inline assembler in IAR EWARM? I have a bit of ass ...

  7. AutoMapper在MVC中的运用04-string映射各种类型、一个属性映射多个属性等

    本篇AutoMapper使用场景: ※ 类型转换,源string类型分别转换成int, DateTime,Type ※ 源和目标都包含复杂类型属性 ※ 把源中的一个属性映射到目标中的多个属性 类型转换 ...

  8. springboot线程池的使用和扩展(转)

    springboot线程池的使用和扩展 我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行, ...

  9. mybatis学习之路----批量更新数据两种方法效率对比

    原文:https://blog.csdn.net/xu1916659422/article/details/77971696/ 上节探讨了批量新增数据,这节探讨批量更新数据两种写法的效率问题. 实现方 ...

  10. C#高级编程小结

    小结 这几章主要介绍了如何使用新的dynamic类型,还讨论了编译器在遇到dynamic类型时会做什么.还讨论了DLP,可以把它包含在简单的应用程序中.并通过Pythin使用DLR,执行Python脚 ...