基于C++的文件操作

在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 openmode,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<<<123;要把3.1415926以5位精度输出:file1<<<3.1415926。

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个字节


文本文件读写:

‘#include

include

using namespace std;

int main()

{

//文本文件打开方式设为可读写

// fstream outfile(“f1.dat”,ios::out|ios::in);

// if (!outfile)

// {

// cout<<”open error!”<

include

include

using namespace std;

struct student

{

char name[20];

int num;

int age;

char sex;

};

int main()

{

student stu[3]={“Li”,1001,18,’f’,”Fun”,1002,19,’f’,”Wa”,1003,17,’m’};

ofstream outfile(“student.dat”,ios::binary);//和文件后缀名没关系,即使写成student.txt还是打开乱码,因为编码是自定义的,默认的字符编码解释不了的。

if (!outfile)

{

cerr<<”open erroe”;

exit(1);

}

// for (int i=0;i<3;i++)

// {

// //outfile.write((char *)&stu[i],sizeof(stu[i]));

// outfile.write((char *)(stu+i),sizeof(stu[i]));

// }

//取代for循环,直接一句话

outfile.write((char *)stu,sizeof(stu));

outfile.close();

//读取
ifstream infile("student.dat",ios::binary);
if (!infile)
{
cerr<<"open error";
exit(1);
}
student stu2[3];
infile.read((char*)stu2,sizeof(stu2));
infile.close(); //打印
for (int i=0;i<3;i++)
{
cout<<stu2[i].name<<endl;
cout<<stu2[i].age<<endl;
cout<<stu2[i].num<<endl;
cout<<stu2[i].sex<<endl; }
return 0;

}



fstream iofile(“student.dat”,ios::in|ios::out|ios::binary);

if(!iofile)

{cout<<”open error”;

exit(1);} //不知道为何新建一个能输入输出的二进制文件总会出错,二上面例子中新建一个输入输出的文本文件可以。

随机访问二进制数据文件

利用seekg(),seekp等成员函数移动指针,随机的访问文件中任意位置上的数据。

举例:(文件读写有两个指针,读文件指针和写指针。)

iofile.seekg(2*sizeof(stu[2]),ios::beg);把输入指针移动到第三个学生数据开头

iofile.read((char *)&stu2[0],sizeof(stu2[0]));

iofile.seekp(2*sizeof(stu[2]),ios::beg);把输出指针移动到第三个学生数据开头

iofile.write((char *)&stu2[0],sizeof(stu2[0]));

文件输入输出C++操作的更多相关文章

  1. python 中文件输入输出及os模块对文件系统的操作

    整理了一下python 中文件的输入输出及主要介绍一些os模块中对文件系统的操作. 文件输入输出 1.内建函数open(file_name,文件打开模式,通用换行符支持),打开文件返回文件对象. 2. ...

  2. C++学习48 对ASCII文件的读写操作

    如果文件的每一个字节中均以ASCII代码形式存放数据,即一个字节存放一个字符,这个文件就是ASCII文件(或称字符文件).程序可以从ASCII文件中读入若干个字符,也可以向它输出一些字符. 对ASCI ...

  3. 用C++进行简单的文件I/O操作-转自VC知识库

    原文请见 http://www.vckbase.com/index.php/wv/1158 序论 我曾发表过文件输入输出的文章,现在觉得有必要再写一点.文件 I/O 在C++中比烤蛋糕简单多了. 在这 ...

  4. C++IO类&文件输入输出

    C++IO类&文件输入输出 istream(输入流)类型,提供输入操作. ostream(输出流)类型,提供输出操作. cin,一个istream对象,从标准输入读取数据. cout,一个os ...

  5. 文件I/O操作

    熟悉文件的各种流类 了解字符的编码 掌握文件I/O操作的相关概念 了解对象的序列化 简单的引入 I:input  由外围输入到内存 O:output  由内存写出到外存. I/O:是相对于内存来说的 ...

  6. IO库----IO类,文件输入输出,string流

    一.IO类 1.IO库类型和头文件表: 头文件 类型 iostream istream,wistream 从流读取数据 ostream,wostream 向流写入数据 iostream,wiostre ...

  7. 第五次程序设计作业 C++计算器雏形 调用文件输入输出

    一.C++计算器作业系列链接 第三次作业:C++计算器雏形 第三次作业附加:代码规范 第四次作业:命令行的调用及计算 MyGithub 二.本次作业相关 要求:第五次程序设计作业 根据这一次的作业要求 ...

  8. LInux文件基础知识和文件目录操作(二)文件I/O操作

    1.文件I/O操作分为两部分来讲解: 第一部分是非缓冲文件操作,这种操作适合于比较小规模文件的读写和对实时性要求很高的设备的数据通信,这类操作是系统调用提供的: 第二部分是缓冲文件操作,所面向的则是大 ...

  9. 文件输入输出实例&Ptask的编写

    前言 最近在写Ptask,顺便了解了如何进行文件读入输出.而在Ptask中最重要,也是最最容易出bug的地方就是文件操作.那么如何进行文件输入输出,在程序中起到重要作用呢? 输入 首先为了保证可以在控 ...

随机推荐

  1. C# 错误!!容量超出了最大容量。参数名: capacity 这个是什么问题呢?

    C# 错误!!容量超出了最大容量.参数名: capacity 这个是什么问题呢?   对于这个问题我纠结了好久老是报错误,报这个错误的原因是应为我加了皮肤的控件,在没有加皮肤控件的时候没有这个错误, ...

  2. idea、jdk、eclispe中空main方法的线程数量不一样,why?

    測试代码: public class Test {     public static void main(String[] args) {         System.out.println(Th ...

  3. 电脑控制手机的另一选择——android vnc server

    近来发现的Android上的原生VNC Server,就是说只要手机上安装并运行这个软件,即可实现电脑上查看并控制手机了. 首先是手机端. 1)下载androidvncserver: http://c ...

  4. 微信小程序 项目实战(三)list 列表页 及 item 详情页

    1.项目结构 2.list 列表页 (1)数据(逻辑) list.js // pages/list/list.js Page({ /** * 页面的初始数据 */ data: { title: '加载 ...

  5. 2016/2/26 jQuery的技术 1,安装 2,语法选择器$ 事件触发 3,常用jQuery函数

    在<网页制作Dreamweaver(悬浮动态分层导航)>中,运用到了jQuery的技术,轻松实现了菜单的下拉.显示.隐藏的效果,不必再用样式表一点点地修改,省去了很多麻烦,那么jQuery ...

  6. Vue框架之组件系统

    1,Vue组件系统之全局组件 1.1Vue全局组件的在实例化调用Vue的模板中导入组件的名称 <!DOCTYPE html> <html lang="zh-cn" ...

  7. debian repository的成长过程

    1 基本概念 1.1 健康的安装 在端系统中的一次健康的安装指的是,在安装的包的集合中,所有的依赖都满足,并且没有冲突存在. 这的健康的安装是相对于端系统而言的,并不是相对于整个repo而言的.对整个 ...

  8. html5--switch选择结构的优化

    html5--switch选择结构的优化 问题: 使用循环语句判断月份是31天还是30天 两点提示: 使用switch多条件判断语句 合理的省略break优化代码 <!DOCTYPE html& ...

  9. silverlight子窗体操作数据库后刷新父窗体

    silverlight子窗体操作数据库后刷新父窗体 作者 Kant 写于 2011 年 07 月 02 日 分类目录 学习笔记, 所有文章 C# Silverlight 代码 刷新 学习 异步刷新 数 ...

  10. 关于追踪qemu 源码函数路径的一个方法

    这阵子一直在研究qemu 磁盘io路径的源码,发现直接看代码是意见非常低效率的事情,qemu是一个比较庞大的家伙(源码部分大概154MB,完全由C语言来完成),整个结构也都非常地复杂,所以从代码上研究 ...