c++文件操作详解

2009-04-16 20:46:35|  分类: C/C++|举报|字号 订阅

C++ 通过以下几个类支持文件的输入输出:

ofstream: 写操作(输出)的文件类 (由ostream引申而来)

ifstream: 读操作(输入)的文件类(由istream引申而来)

fstream: 可同时读写操作的文件类 (由iostream引申而来)

打开文件(Open a file)

对这些类的一个对象所做的第一个操作通常就是将它和一个真正的文件联系起来,也就是说打开一个文件。被打开的文件在程序中由一个流对象(stream object)来表示 (这些类的一个实例) ,而对这个流对象所做的任何输入输出操作实际就是对该文件所做的操作。

要通过一个流对象打开一个文件,我们使用它的成员函数open():void open (const char * filename, openmode mode);

这里filename 是一个字符串,代表要打开的文件名,mode 是以下标志符的一个组合: ios::in 为输入(读)而打开文件

ios::out 为输出(写)而打开文件

ios::ate 初始位置:文件尾

ios::app 所有输出附加在文件末尾

ios::trunc 如果文件已存在则先删除该文件

ios::binary 二进制方式

这些标识符可以被组合使用,中间以”或”操作符(|)间隔。例如,如果我们想要以二进制方式打开文件"example.bin" 来写入一些数据,我们可以通过以下方式调用成员函数open()来实现:ofstream file;

file.open ("example.bin", ios::out | ios::app | ios::binary);

ofstream, ifstream 和 fstream所有这些类的成员函数open 都包含了一个默认打开文件的方式,这三个类的默认方式各不相同: 类 参数的默认方式

ofstream ios::out | ios::trunc

ifstream ios::in

fstream ios::in | ios::out

只有当函数被调用时没有声明方式参数的情况下,默认值才会被采用。如果函数被调用时声明了任何参数,默认值将被完全改写,而不会与调用参数组合。

由于对类ofstream, ifstream 和 fstream 的对象所进行的第一个操作通常都是打开文件,这些类都有一个构造函数可以直接调用open 函数,并拥有同样的参数。这样,我们就可以通过以下方式进行与上面同样的定义对象和打开文件的操作:ofstream file ("example.bin", ios::out | ios::app | ios::binary);

两种打开文件的方式都是正确的。

你可以通过调用成员函数is_open()来检查一个文件是否已经被顺利的打开了:bool is_open();

它返回一个布尔(bool)值,为真(true)代表文件已经被顺利打开,假( false )则相反。

关闭文件(Closing a file)

当文件读写操作完成之后,我们必须将文件关闭以使文件重新变为可访问的。关闭文件需要调用成员函数close(),它负责将缓存中的数据排放出来并关闭文件。它的格式很简单:void close ();

这个函数一旦被调用,原先的流对象(stream object)就可以被用来打开其它的文件了,这个文件也就可以重新被其它的进程(process)所有访问了。

为防止流对象被销毁时还联系着打开的文件,析构函数(destructor)将会自动调用关闭函数close。

文本文件(Text mode files)

类ofstream, ifstream 和fstream 是分别从ostream, istream 和iostream 中引申而来的。这就是为什么 fstream 的对象可以使用其父类的成员来访问数据。

一般来说,我们将使用这些类与同控制台(console)交互同样的成员函数(cin 和 cout)来进行输入输出。如下面的例题所示,我们使用重载的插入操作符<<: // writing on a text file

#include <fiostream.h>

int main () {

ofstream examplefile ("example.txt");

if (examplefile.is_open()) {

examplefile << "This is a line.\n";

examplefile << "This is another line.\n";

examplefile.close();

}

return 0;

}

file example.txt

This is a line.

This is another line.

从文件中读入数据也可以用与 cin的使用同样的方法: // reading a text file

#include <iostream.h>

#include <fstream.h>

#include <stdlib.h>

int main () {

char buffer[256];

ifstream examplefile ("example.txt");

if (! examplefile.is_open())

{ cout << "Error opening file"; exit (1); }

while (! examplefile.eof() ) {

examplefile.getline (buffer,100);

cout << buffer << endl;

}

return 0;

}

This is a line.

This is another line.

上面的例子读入一个文本文件的内容,然后将它打印到屏幕上。注意我们使用了一个新的成员函数叫做eof ,它是ifstream 从类 ios 中继承过来的,当到达文件末尾时返回true 。

状态标志符的验证(Verification of state flags)

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

bad()

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

fail()

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

eof()

如果读文件到达文件末尾,返回true。

good()

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

要想重置以上成员函数所检查的状态标志,你可以使用成员函数clear(),没有参数。

获得和设置流指针(get and put stream pointers)

所有输入/输出流对象(i/o streams objects)都有至少一个流指针:

ifstream, 类似istream, 有一个被称为get pointer的指针,指向下一个将被读取的元素。

ofstream, 类似 ostream, 有一个指针 put pointer ,指向写入下一个元素的位置。

fstream, 类似 iostream, 同时继承了get 和 put

我们可以通过使用以下成员函数来读出或配置这些指向流中读写位置的流指针:

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)。它可以是: ios::beg 从流开始位置计算的位移

ios::cur 从流指针当前位置开始计算的位移

ios::end 从流末尾处开始计算的位移

流指针 get 和 put 的值对文本文件(text file)和二进制文件(binary file)的计算方法都是不同的,因为文本模式的文件中某些特殊字符可能被修改。由于这个原因,建议对以文本文件模式打开的文件总是使用seekg 和 seekp的第一种原型,而且不要对tellg 或 tellp 的返回值进行修改。对二进制文件,你可以任意使用这些函数,应该不会有任何意外的行为产生。

以下例子使用这些函数来获得一个二进制文件的大小: // obtaining file size

#include <iostream.h>

#include <fstream.h>

const char * filename = "example.txt";

int main () {

long l,m;

ifstream file (filename, ios::in|ios::binary);

l = file.tellg();

file.seekg (0, ios::end);

m = file.tellg();

file.close();

cout << "size of " << filename;

cout << " is " << (m-l) << " bytes.\n";

return 0;

}

size of example.txt is 40 bytes.

二进制文件(Binary files)

在二进制文件中,使用<< 和>>,以及函数(如getline)来操作符输入和输出数据,没有什么实际意义,虽然它们是符合语法的。

文件流包括两个为顺序读写数据特殊设计的成员函数:write 和 read。第一个函数 (write) 是ostream 的一个成员函数,都是被ofstream所继承。而read 是istream 的一个成员函数,被ifstream 所继承。类 fstream 的对象同时拥有这两个函数。它们的原型是:

write ( char * buffer, streamsize size );

read ( char * buffer, streamsize size );

这里 buffer 是一块内存的地址,用来存储或读出数据。参数size 是一个整数值,表示要从缓存(buffer)中读出或写入的字符数。 // reading binary file

#include <iostream>

#include <fstream.h>

const char * filename = "example.txt";

int main () {

char * buffer;

long size;

ifstream file (filename, ios::in|ios::binary|ios::ate);

size = file.tellg();

file.seekg (0, ios::beg);

buffer = new char [size];

file.read (buffer, size);

file.close();

cout << "the complete file is in a buffer";

delete[] buffer;

return 0;

}

The complete file is in a buffer

 
格式输出:
// field width
#include <iostream> // std::cout, std::left int main () {
std::cout << << '\n';
std::cout.width();
std::cout << << '\n';
std::cout.fill('x');
std::cout.width();
std::cout << std::left << << '\n';
return ;
}

output:


100xxxxxxxxxxxx

文件操作fstream的更多相关文章

  1. C++文件操作(fstream)

    C++ 通过以下几个类支持文件的输入输出: ofstream: 写操作(输出)的文件类 (由ostream引申而来) ifstream: 读操作(输入)的文件类(由istream引申而来) fstre ...

  2. C++文件操作详解(ifstream、ofstream、fstream)

    C++ 通过以下几个类支持文件的输入输出: ofstream: 写操作(输出)的文件类 (由ostream引申而来) ifstream: 读操作(输入)的文件类(由istream引申而来) fstre ...

  3. 【学习笔记】C++文件操作详解(ifstream、ofstream、fstream)

    C++ 通过以下几个类支持文件的输入输出: ofstream: 写操作(输出)的文件类 (由ostream引申而来) ifstream: 读操作(输入)的文件类(由istream引申而来) fstre ...

  4. C++ fstream文件操作

    代码如下: #include "stdafx.h" #include<string> #include<iostream> //是因为要使用cout #in ...

  5. C语言的fopen函数(文件操作/读写)

    头文件:#include <stdio.h> fopen()是一个常用的函数,用来以指定的方式打开文件,其原型为:    FILE * fopen(const char * path, c ...

  6. MFC文件操作

    文件操作:二进制文件和文本文件的区别.二进制文件将数据在内存中存在的模式原封不动的搬到文件中,而文本文件是将数据的asc码搬到文件中.首先做一个读写文件的菜单,在CxxView里响应1.C的方式:fw ...

  7. C/C++文件操作2

    一.流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下: typedef struct { int level; /* fill/empty level of ...

  8. C/C++ 文件操作

    C/C++ 文件操作大概有以下几种 1.C的文件操作: 2.C++的文件操作: 3.WINAPI的文件操作: 4.BCB库的文件操作: 5.特殊文件的操作. 当然了,水题时最常用的当然还是: freo ...

  9. C++ builder的文件操作

    在编程的过程中,文件的操作是一个经常用到的问题,在C++Builder中,可以使用多种方法对文件操作,下面我就按以下几个部分对此作详细介绍,就是:1.基于C的文件操作:2.基于C++的文件操作:3.基 ...

随机推荐

  1. ArrayList底层实现

    ArrayList 底层是有数组实现,实际上存放的是对象的引用,而不是对象本身.当使用不带参的构造方法生成ArrayList对象时,实际会在底层生成一个长度为10的数组 当添加元素超过10的时候,会进 ...

  2. SpringBoot(六)_AOP统一处理请求

    什么是AOP AOP 是一种编程范式,与编程语言无关: 将通用逻辑从业务逻辑中分离出来(假如你的业务是一条线,我们不在业务线上写一行代码就能完成附加任务!我们会把代码写在其他的地方): 具体实现 (1 ...

  3. filebeat向kafka中传输数据报WARN Failed to connect to broker DOMSDev07:9092: dial tcp: lookup DOMSDev07: getaddrinfow: No such host is known.解决方法

    打开filebeat客户端所在机器C:\Windows\System32\drivers\etc目录,找到hosts文件 以记事本形式打开,在底部追加 “IP 主机名” 即可

  4. BZOJ3142 HNOI2013数列(组合数学)

    考虑差分序列.每个差分序列的贡献是n-差分序列的和,即枚举首项.将式子拆开即可得到n*mk-1-Σi*cnt(i),cnt(i)为i在所有差分序列中的出现次数之和.显然每一个数出现次数是相同的,所以c ...

  5. ORA-01410: 无效的 ROWID

    视图查询单表是有这个东西的,但是视图的SQL涉及多表关联,就没这个rowid了,要么自己写个,要么不用这个ROWID做啥动作

  6. Educational Codeforces Round 48

    题目地址 Edu48 A.Death Note 翻译 你有一个无穷页的本子,每一页可以写\(m\)个名字, 你在第\(i\)天要写\(a_i\)个名字,如果这一页恰好写满了,你就会翻页, 问每天的翻页 ...

  7. 【bzoj1187】 HNOI2007—神奇游乐园

    http://www.lydsy.com/JudgeOnline/problem.php?id=1187 (题目链接) 题意 一个$n*m$的矩阵,其中每一个位置有一个权值,求一条回路使得经过的位置的 ...

  8. pickle 在python2 to python3 编码出现错误

    pickle.load(file) UnicodeDecodeError: 'ascii' codec can't decode byte 0xf5 in position 2: ordinal no ...

  9. Levenshtein Distance莱文斯坦距离算法来计算字符串的相似度

    Levenshtein Distance莱文斯坦距离定义: 数学上,两个字符串a.b之间的莱文斯坦距离表示为levab(|a|, |b|). levab(i, j) = max(i, j)  如果mi ...

  10. bzoj 1193 贪心+bfs

    1193: [HNOI2006]马步距离 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2015  Solved: 914[Submit][Statu ...