C++程序设计案例实训教程第15章

15章  输入输出与文件第四篇  输入输出处理

    

                第15章  输入输出与文件

(本资料qq讨论群112133686)

C语言中,用printf()scanf()进行输入输出,往往不能保证所输入输出的数据是可靠的、安全的。C++语言的输入输出优于C语言中的printf()scanf()C++通过输入输出I/O类库来实现丰富的I/O功能,但是比较复杂有许多细节需要掌握。C++的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一对象。流表示了信息从源到目的端的流动。在C++中,输入输出流被定义为类,C++I/O库中的类称为流类(stream class)。用流类定义的对象称为流对象。coutcin并不是C++语言中提供的语句,它们是iostream类的对象,C++对文件的输入输出需要用ifstreamofstream类,ifstream支持对文件的输入操作,ofstream支持对文件的输出操作。

本章举的实例都是C++输入输出相关的例子,如怎样用流类库输出一个文件、对二进制文件读写(和文本文件读写)、获取文件长度和随机写入数据,以及输入输出库函数例子,通过这些实例让读者加深对输入输出的理解。本章重点是文件输入和输出的实例,这些对于初学者反复多实践,加深理解,举一反三。

15.1  输入输出概述

案例15-1  使用流类库输出一个文件

【案例描述】

本章开始演示C++输入输出系统的实例,程序的输入指的是在输入文件中把数据传送给程序,程序的输出指的是从程序把数据传送给输出文件。本实例创建个文件,写入数据,然后读取显示。本例效果如图15-1所示。

【实现过程】

Hello world!”字符串输出到“example.txt”文本文件中。以生成的“example.txt”文件作为输入文件,通过两次fin >> str;,读取内容,并在屏幕上输出。代码如下:

#include<iostream>

#include <fstream>

#include <string>

using namespace std;

int main() {   

cout <<"流类库输出文件演示:"<<endl;

ofstream fout("example.txt"); //磁盘文件的输出

if(!fout) //不能打开文件

{ cerr << "打开文件错误!" << endl; //输出出错信息

exit(1); //结束程序

}

fout << "Hello world!"<< endl; //写入文件内容

fout.close(); //关闭磁盘文件

ifstream fin("example.txt"); //磁盘文件的输入

if(!fin) { //不能打开文件

cerr << "打开文件错误!" << endl;

exit(1);}

string str; //定义string类字符串

fin >> str; //读取文件内容

cout << str << " ";

fin >> str; //读取文件内容

cout << str << endl;                      //打印输出内容

system("pause");

return 0;

}

【案例分析】

1ostream类提供了格式化和无格式化的输出功能。包括:

— 用插入操作符(<<)输出标准类型数据;

— put成员函数输出字符;

— write成员函数实现无格式输出。

最常用的输出方法是在cout上用插入操作符(<<),插入操作符可以接受任何标准类型的实参,包括const char *、标准库stringcomplex等类型。实参可以是任何表达式包括函数调用,只要其结果是能被插入操作符能接受的数据类型即可。

2C++中的I/O是以流(stream)的形式出现的。

流的输入操作是字节从外部设备(包括键盘、磁盘、网络连接)输入到内存,是字节从设备到内存的流动。输出操作是从内存输出到外部设备(如显示器、打印机、磁盘、网络连接),是字节从内存到外部设备的流动。

 

提示:流实际上是一个处于传输状态的字节序列,是字节在对象之间的“流动”,流的操作包括输入与输出。

案例15-2  如何获得文件长度

【案例描述】

实际编程中常需要知道一个文件内容长度,如读取图像数据时知道文件有多长,以便初始化缓冲区。本例演示输入一个文件求文件长度的功能,效果如图15-2所示。

 

15-2  如何获得文件长度

【实现过程】

打开一个文件example.txt,取得文件头的位置begin和取得文件尾的位置end,它们的差值(end-begin)就是文件的长度。代码如下:

#include <iostream>

#include <fstream>

using namespace std;

int main () {

  long begin,end;

  ifstream myfile ("example.txt"); //磁盘文件的输入

  begin = myfile.tellg(); //返回读指针相对于文件头的位置

  myfile.seekg (0, ios::end); //输出文件中的指针从文件尾

  end = myfile.tellg(); //返回读指针相对于文件头的位置

  myfile.close(); //关闭磁盘文件

  cout << "example.txt size is: " << (end-begin) << " bytes.\n";

  return 0;

}

【案例分析】

1)上述代码long tellg()回读指针相对于文件头的位置。

2stream& seekg(long off, ios::seek_dir dir ),设定读取指针到距离文件某一特定位置off个字节的位置。特定位置由dir确定,dirios::begios::curios::end之一。当特定位置为ios::end时,off应为负数。

案例15-3  使用system()函数使屏幕停止

【案例描述】

如果调试控制台程序中,很多时候点击“启动调试”后是一闪而过,此时可有两种方法让cmddos调试屏幕暂停,一个是代码加上system("pause"),对这个读者很熟悉;另一个是在主函数main()return 0前加上两句:cin.get()。本例效果如图15-3所示。

 

15-3  使用system()函数使屏幕停止

【实现过程】

定义一个函数simon(),输入的是整数,主函数中输入整数,调用simon()显示输入整数,cin.get()屏幕暂停,让程序等待键击。代码如下:

#include <tchar.h>

#include<iostream>

void simon(int);

using namespace std; //这是一个使用std;名称空间的例子

int _tmain(int argc, _TCHAR* argv[])

{

simon(18);

cout<<"请输入一个整数: ";

int count;

cin>>count; //输入取得的整数

simon(count); //显示输入整数

cout<<"完成!"<<endl;

cin.get(); //这两行是使调试屏幕暂停,不会一闪而过

cin.get(); //让程序等待键击

return 0; //退出主函数

}

void simon(int n)

{

cout<<"现在整数是: "<<n<<" 测试!"<<endl;

}

【案例分析】

1)代码中调用了一个getch()库函数,程序中的作用使屏幕暂停,当程序执行到此函数时就暂停,等待输入一个任意字符后,程序继续向下执行。这样做的好处是,可以使用户看清封面和主子菜单

2cin.get(字符数组名,接收字符数目)用来接收一行字符串,可以接收空格。

 

提示:VC++下,cin.get()如果不包含using namespace std指令,那么必须使用std::前缀std::cin.get

15.2  高层I/O

案例15-4  读写二进制文件

【案例描述】

二进制文件是指含ASCII码字符外的数据的文件,它不能由文本编辑软件打开。在实际应用中,大多数文件都是二进制文件,如图像文件、影像文件等。这是一个二进制文件读写的例子,效果如图15-4所示。

 

15-4  读写二进制文件

【实现过程】

创建ofstream流对象out对应于二进制文件example.asc,打开文件,以二进制形式写入浮点数字符数组fnum,以二进制形式按格式fnum读出数据并显示读出数据。代码如下:

#include <iostream>

#include <fstream>

using namespace std;

int main(void){

   float fnum[4] = {11.22, -33.44, 55.66, 77.88};//定义浮点数字符数组

   int i;

   //创建ofstream流对象out

   ofstream out("example.asc", ios::out | ios::binary);

   if(!out){ //不能打开文件

      cout << "Cannot open file.";

      exit (1); //结束程序

   }

   out.write((char *) &fnum, sizeof(fnum)); //以二进制形式写入numbers.asc

   out.close(); //关闭流

   for (i=0; i<4; i++)

      fnum[i] = 0.0;

   //创建ifstream流对象in,以便从numbers.asc中读取信息

   ifstream in("example.asc", ios::in | ios::binary);

   if(!in) { //不能打开文件

      cout << "Cannot open file.";

      exit (1); //结束程序

   }

   in.read((char *) &fnum, sizeof(fnum)); //以二进制形式读入数据

   cout << in.gcount() << " bytes read." << endl; //显示读入数据字符数

   for (i=0; i<4; i++)

      cout << fnum[i] << " "; //标准输出,屏幕显示

   in.close(); //关闭流

   system("pause");

}

【案例分析】

1)在代码中,二进制文件example.asc的读写利用istream类的成员函数readwrite来实现。这两个成员函数的原型为:

istream& read(char *buffer,int len);

ostream& write(const char * buffer,int len); 

字符指针buffer指向内存中一段存储空间,len是读写字节数。调用的方式如:

a. write(p1,50); b. read(p2,30);。

2)输出二进制文件的方法是使用write()成员函数。输入二进制文件使用成员函数read()每次读取固定长度的数据,同样用eof()判断是否到达文件尾。

 

提示:C++语言把每个文件看成是一个有序的字节流。文件打开时,就创建一个对象,并将这个对象和某个流关联起来。包含<iostream>时,会自动生成cincoutcerrclog这四个对象,与这些对象关联的流提供与文件通信的方法(文件操作)。

案例15-5  读写记事本

【案例描述】

文本文件是以ASCII表示的文件如记事本。在文件操作前,需要将程序与被操作的文件联系起来,使程序可以“引用”文件。在程序内定义一个文件类的对象,由该对象与文件发生联系,程序内所有的与文件的操作都是对该对象的操作。本实例举文本文件读写操作,效果如图15-5所示。

【实现过程】

键盘读入一行字符再输出到“example.txt”文本文件中。以生成的“example.txt”文件作为输入文件,通过两次infile>>line;,读取内容,并在屏幕上输出。代码如下:

#include <iostream>

#include <fstream>

#include  <fstream>

#include <string>

using namespace std;

void main() {

char line[180];

fstream myfile; //建立文件流

myfile.open("example.txt", ios::out); //定义文件流对象,打开磁盘文件

if(!myfile) { //如果打开失败

cerr<<"File open or create error!"<<endl;

exit(1);

}

     cin.getline(line,80); //从键盘读入一行字符

 

myfile<<line; //向磁盘文件输出数据

myfile.close(); //关闭磁盘文件

 

      ifstream infile; //定义输入文件流对象

infile.open("example.txt"); //以输入方式打开磁盘文件

if (infile.is_open())

{

while (! infile.eof() )

{

infile>>line; //从磁盘文件读入

cout <<"读取文件内容为:"<<line << endl; //在显示器上显示

}

infile.close(); //关闭磁盘文件

}else //如果打开失败

cout << "Unable to open file";

system("pause");

}

【案例分析】

1C++的文件I/O模式分为两种文本模式与二进制模式,默认模式为文本模式。当使用文本模式时,输出到文件的内容为ASCII码字符(包括回车、换行)。也就是说,文本文件中只能存储ASCII码字

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值