一、文件的读写

前面所提,流的读写主要有<<, >>, get, put, read, write 等操作,ofstream 继承自ostream, ifstream 继承自 istream,故操作函数都是一致的。

 C++ Code 
1
2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

 
#include <iostream>


#include <fstream>


#include <string>


#include <cassert>


using 
namespace std;

int main(
void)

{

    ofstream fout(
"test.txt");

    fout << 
"abc" << 
" " << 
;

    fout.close();

ifstream fin(
"test.txt");

    string s;

    
int n;

    
//fin>>n>>s;
    fin >> s >> n;

    cout << s << 
" " << n << endl;

ofstream fout1(
"test2.txt");

    assert(fout1);

    
char ch;

for (
int i = 
; i < 
; i++)

    {

        ch = 
'A' + i;

        fout1.put(ch);

    }

    fout1.close();

ifstream fin1(
"test2.txt");

    
while (fin1.get(ch))

    {

        cout << ch;

    }

    cout << endl;

return 
;

}

二、二进制文件的读写

二进制文件不同于文本文件,它可用于任何类型的文件(包括文本文件)
对二进制文件的读写可采用从istream类继承下来的成员函数read()和从ostream类继承下来的成员函数write()
文件打开操作时使用枚举常量ios::binary,例如:ofstream fout(“binary.dat”,ios::out | ios::binary);

(一)、write成员 函数

函数功能:以字节位单位向文件流中写入整块数据,最有价值的应用可以处理结构体变量和类对象
函数原型:

ostream& write( const char* pch, int nCount );

函数参数:
pch 写入的数据的指针
nCount 写入数据的字节大小

(二)、read 成员 函数

函数功能:从文件流中读出整块数据
函数原型:

istream& read( char* pch, int nCount );

函数参数:
pch 用来接收数据的指针
nCount 读取的字节数的大小

 C++ Code 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

 
#include <cassert>


#include <iostream>


#include <fstream>


#include <string>

using 
namespace std;

struct Test

{

    
int a;

    
int b;

};

int main(
void)

{

    ofstream fout(
"test3.txt", ios::out | ios::binary); 
// 二进制方式打开,'\n'不做转换
    fout << 
"ABC\n"; 
// << 是以文本方式写入
    fout.close();

Test test = { 

 };

    ofstream fout1(
"test4.txt", ios::out | ios::binary);

    fout1.write(
reinterpret_cast<
char *>(&test), 
sizeof(Test));

    
// 二进制方式写入后用文本编辑器打开test4.txt 乱码
    fout1.close();

Test test2;

    ifstream fin(
"test4.txt", ios::in | ios::binary);

    fin.read(
reinterpret_cast<
char *>(&test2), 
sizeof(Test));

    cout << test2.a << 
" " << test2.b << endl;

ofstream fout2(
"test5.txt", ios::out | ios::binary);

    fout2 << 
"abc" << 

// << 是以文本方式写入
    fcout2.close();

return 
;

}

在window下以文本方式打开文件,则写入时遇到'\n' , 转换为'\r\n',以二进制方式打开则不做转换,故test3.txt 文件大小为4个字节。

而写入100(write 是以二进制方式写入)就不再是写入'1', '0' ,' 0' 的ascii 码,而是按照内存本来二进制形式写入,故用文本编辑器打开test4.txt 时会出现乱码。文件大小为8个字节(两个int)

同理,test5.txt 虽然以二进制打开,但是以文本方式(<< 是以文本方式写入)写入的,故写入200后用文本编辑器打开不会出现乱码,文件大小为6个字节。

有关文本文件与二进制文件的区别,请参考这里

使用read, write 读取string 的时候需要注意,string 实际上内部是一些指针成员,sizeof(string)=32 (跟编译器实现有关),即string 大小是一定的,而它的指针成员保存的字符串长度不一定是32,故我们应该这些读写:

 C++ Code 

1

2

3

4

5

6

7

8

9

 
string str1 = 
"fdsfafsdsf";


int len = str1.length();

ofstream fout(
"test6.txt", ios::out | ios::binary);

fout.write(str1.data(), str1.length());

string str2;

str2.resize(len);

ifstream fin(
"test6.txt", ios::in | ios::binary);

fin.read(&str2[
], len);

如果像这样写入  fout.write((char*)&str1, sizeof(str1)); 一定是错误的,因为写入的是str1 的指针成员,而不是指针成员指向的字符串,而且str1 的大小恒等于32。

三、文件随机读写

(一)、当前文件流活动指针

文件流指针用以跟踪发生 I/O 操作的位置
每当从流中读取或写入一个字符,当前活动指针就会向前移动
当打开方式中不含有ios::ate或ios::app选项时,则文件指针被自动移到文件的开始位置,即字节地址为0的位置。

(二)、文件的随机读写 seekp和seekg

seekp 和 seekg 类似与C库的fseek, linux系统调用的lseek。

函数功能

seekp:设置输出文件流的文件流指针位置

seekg:设置输入文件流的文件流指针位置

函数原型:

ostream& seekp( streampos pos );

ostream& seekp( streamoff off, ios::seek_dir dir );

istream& seekg( streampos pos );

istream& seekg( streamoff off, ios::seek_dir dir );

函数参数

pos:新的文件流指针位置值

off:需要偏移的值

dir:搜索的起始位置

dir参数用于对文件流指针的定位操作上,代表搜索的起始位置
在ios中定义的枚举类型:

enum seek_dir {beg, cur, end};

每个枚举常量的含义:
ios::beg:文件流的起始位置
ios::cur:文件流的当前位置
ios::end:文件流的结束位置

tellp 和 tellg 类似C库的ftell,,linux 系统调用的lseek(fd, 0, SEEK_CUR);

函数功能

tellp:获得输出的文件流指针的当前位置,以字节为单位

tellg:获得输入的文件流指针的当前位置,以字节为单位

函数原型:

streampos tellp();

streampos tellg();

函数返回值:实际上是一个long类型

 C++ Code 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

 
#include <cassert>


#include <iostream>


#include <fstream>


#include <string>

using 
namespace std;

int main(
void)

{

    ifstream fin(
"test7.txt");

    assert(fin);

    fin.seekg(
);
//位置从0开始计数

char ch;

    fin.get(ch);

    cout << ch << endl;

fin.seekg(-
, ios::end); 
//end 实际上是EOF位置
    fin.get(ch);

    cout << ch << endl;

fin.seekg(
, ios::end);

    streampos pos = fin.tellg();

    cout << pos << endl;

return 
;

}

假设test7.txt 现在存放abcdefg 7个字符,则输出为c g 7 .

参考:

C++ primer 第四版
Effective C++ 3rd
C++编程规范

从零开始学C++之IO流类库(三):文件的读写、二进制文件的读写、文件随机读写的更多相关文章

  1. 从零开始学C++之IO流类库(二):文件流(fstream, ifstream, ofstream)的打开关闭、流状态

    一.文件流 ofstream,由ostream派生而来,用于写文件 ifstream,由istream派生而来, 用于读文件 fstream,由iostream派生而来,用于读写文件 二.打开文件 说 ...

  2. 从零开始学C++之IO流类库(四):输出流格式化(以操纵子方式格式化 以ios类成员函数方式格式化)

    一.以操纵子方式格式化 数据输入输出的格式控制使用系统头文件<iomanip>中提供的操纵符.把它们作为插入操作符<<的输出对象即可.如setiosflags.setw.set ...

  3. 代码实现:当我们下载一个试用版软件,没有购买正版的时候,每执行一次就会提醒我们还有多少次使用机会用学过的IO流知识,模拟试用版软件,试用10次机会,执行一次就提示一次您还有几次机会,如果次数到了提示请购买正版

    package com.loaderman.test; import java.io.BufferedReader; import java.io.FileReader; import java.io ...

  4. 从零开始学 Web 之 JS 高级(三)apply与call,bind,闭包和沙箱

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  5. 从零开始学 Web 之 移动Web(三)Zepto

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  6. 从零开始学 Web 之 Vue.js(三)Vue实例的生命周期

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  7. Java中的IO流(三)

    上一篇<Java中的IO流(二)>把学习Java的字符流以及转换流作了一下记录,从本篇开始将把IO流中对文件或文件夹操作的对象File类的学习进行一下记录. 一,File类的构造函数及字段 ...

  8. 【重学Java】IO流

    IO流的UML类图 File类 File类概述和构造方法[应用] File类介绍 它是文件和目录路径名的抽象表示 文件和目录是可以通过File封装成对象的 对于File而言,其封装的并不是一个真正存在 ...

  9. java基础(二十)IO流(三)

    这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...

随机推荐

  1. bootstrap 智能表单 demo示例

    1.基本配置,支持的元素类型 2.自动布局 3.自定义布局 4.自定义表单 5.数据绑定 6.带验证的表单 7.智能搜索 8.级联下拉 9.图片上传 图片有点大了,屏幕不够大的话可能看的不习惯,没事 ...

  2. MATLAB - 为什么imshow(g,[])可以正常显示,而imshow(g)却显示空白图像?

    Q:为什么imshow(g,[])可以正常显示,而imshow(g)却显示空白图像? A:数据类型如果是double,imshow的处理范围是0-1数据类型如果是uint8,imshow的处理范围是0 ...

  3. JavaSE复习日记 : 条件判断语句

    /* 条件控制语句:if(){}else{} 语法: 第一种结构:有不执行的情况 if(boolean表达式){ //第一位真,就执行里面的语句,为假就不执行 java语句; } 第二种结构: if( ...

  4. QT中QWidget、QDialog及QMainWindow的区别

    本文转自http://www.cnblogs.com/aqxin/archive/2011/05/23/2054156.html QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基 ...

  5. mysql中varchar最长多少

    4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无论存放的是数字.字母还是UTF8 ...

  6. [LeetCode]题解(python):106-Construct Binary Tree from Inorder and Postorder Traversal

    题目来源: https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/ 题意分析 ...

  7. appium 学习各种小功能总结--功能有《滑动图片、保存截图、验证元素是否存在、》---新手总结(大牛勿喷,新手互相交流)

    1.首页滑动图片点击 /** * This Method for swipe Left * 大距离滑动 width/6 除数越大向左滑动距离也越大. * width:720 *height:1280 ...

  8. 一张图解释---Java多态

    1.向上转型:编译器自动进行,不需要声明 Snowboard s = new Snowboard (); Object o = s; (相当于指向Snowboard的内部Object实例,所有类都继承 ...

  9. java源码解析——Stack类

    在java中,Stack类继承了Vector类.Vector类和我们经常使用的ArrayList是类似的,底层也是使用了数组来实现,只不过Vector是线程安全的.因此可以知道Stack也是线程安全的 ...

  10. OpenCV之Python学习笔记

    OpenCV之Python学习笔记 直都在用Python+OpenCV做一些算法的原型.本来想留下发布一些文章的,可是整理一下就有点无奈了,都是写零散不成系统的小片段.现在看 到一本国外的新书< ...