本次实验说明
1. 实验前,请对照「实验准备」,复习必要的知识,尤其是第11章文件I/O示例程序,通过运行和观察,熟悉和掌
握文件I/O方法和一些成员函数用法。
2. 「Part3 应用编程实践」两道编程题目,难度没有很大,但是,因为涉及文件I/O、随机函数等的处理,在细节
处容易出错。错误一多,就容易让人觉得混乱,不知道从哪里入手。先理顺思路,再分模块完成。也可以先写
一些小程序,逐步测试,逐步实现。
实验目的
1. 理解流的概念,掌握流类库的基础知识
2. 掌握标准I/O及常用的格式控制
3. 掌握文件I/O的方法
实验准备
请结合第11章课件和教材复习以下内容:
1. 概念
流
插入运算符<<在使用时,向流中插入意指什么?
提取运算符>>在使用时,从流中提取意指什么?
几个标准I/O流对象:cin, cout, cerr, clog
标准I/O流类的继承/派生层次关系
2. 语法和应用
格式控制方法
使用ios类的成员函数进行格式控制
使用操纵符函数进行格式控制
使用文件流类实现文件I/O的步骤和方法,以及常用的一些成员函数或普通函数,如××.open(), ××.close(),
××.fail(), ××.is_open(),××.get(), ××.getline(), getline()等等。
说明:getline()既有成员函数,也有普通函数,其函数原型稍有不同,主要是形参类型和返回值。请在
cppreference.com输入getline,结合页面的代码示例,学习普通函数getline()和成员函数getline()的用法
及区别。教材p494也有少量介绍。
3. 示例
运行第11章课件及教材内格式化控制及文件I/O示例,结合运行结果,复习C++中格式化控制和文件I/O方法。
实验内容
Part1 验证性实验
1. 合并两个文件到新文件中。文件名均从键盘输入。
运行程序ex1.cpp,结合运行结果及源码中注释,理解和体会文件I/O的方法。
程序文件ex1.cpp源码
实验结果如下:
Part2 基础练习
使用文件I/O流,以文本方式打开Part1中合并后的文件,在文件最后一行添加字符"merge successfully"。
#include<iostream> #include<fstream> #include <cstdlib> #include<string> using namespace std; int main(){ ofstream file; file.open("3.txt",ios_base::app); if(!file.is_open()) { cerr<<"fail to open the file"<< endl; system("pause"); exit(0); } file<<endl; file<<"merge successfully"; file.close(); system("pause"); return 0; }
Part3 应用编程实践
1. 已知名单列表文件list.txt。编写一个应用程序,实现从名单中随机抽点n位同学(n由键盘输入),在屏幕上显
示结果,同时也将结果写入文本文件,文件名自动读取当天系统日期,如20190611.txt。
必做
用c++编程实现题目的基本功能要求
问题分析&提示随机抽点,可以借助随机函数rand()和srand()
① int rand(void)返回一个0~RAND_MAX之间的伪随机数;头文件(也有的在)rand()函数原型及使用示例参考
② void srand (unsigned int seed);为rand()设置随机种子。通常以时间作为随机种子,即srand(time(NULL))头文件(也有的在), srand()函数运行及使用示例参考
自动获取当天系统日期作为文件名可以利用标准库中与时间相关的函数,稍作处理,转换成string类型,然后用作文件名。
鼓励每位同学自行尝试编程实现上述要求。这里,也以函数的形式提供实现好的版本,可以直接作为工具函数调用,以获取当前系统日。
//这个头文件里包含了可用工具函数的声明 #include <string> using std::string; // 函数声明 // 返回当前系统时间,格式诸如20190611 string getCurrentDate();
#include "utils.h" #include <ctime> using std::string; const int SIZE = 20; // 函数功能描述:返回当前系统日期 // 参数描述:无参数 // 返回值描述:以string类型返回系统当前日期,格式诸如20190611 string getCurrentDate() { time_t now = time(0); // 获取当前系统日历时间 struct tm *local_time = localtime(&now); // 把系统日历时间转换为当地时间 char date[SIZE]; strftime(date, SIZE, "%Y%m%d", local_time); return (string(date)); }
#include <iostream> #include <string> #include <fstream> #include <cstdlib> #include <ctime> #include "utils.h" using namespace std; int main() { string filename,list,line; filename=getCurrentDate(); cout<<filename<<endl; int n; cout<<"输入名单列表文件名:"; cin>>list; cout<<"输入随机抽点人数: "; cin>>n; ifstream fin; ofstream fout; fin.open(list, ios_base::in); if (!fin.is_open()) { cerr<<"fail to open "<<list<<endl; system("pause"); exit(0); } fout.open(filename, ios_base::app); if (!fout.is_open()) { cerr<<"fail to open "<<filename<< endl; system("pause"); exit(0); } srand(time(0)); while(n--){ int m=rand()%83; fin.seekg(0);//回头 for(int j=1;j<=m;j++) getline(fin,line); cout<<line<<endl; fout<<line<<endl; } fout<<endl; fin.close(); fout.close(); system("pause"); return 0; }
2. 编程统计英文文本文件中字符数(包括空格)、单词数、行数。文件名由键盘输入。
必做用c++编程实现题目的基本功能
#include <iostream> #include <fstream> #include <string> using namespace std; int main() { string filename; char c; int a=0,words=1,lines=1;//a字符数 b单词数 c行数 cout<<"输入要统计的文本文件名:" ; cin>>filename; ifstream fin; fin.open(filename); if(!fin) { cout<< "fail to open file "<<endl; system("pause"); exit(0); } while(fin.get(c)){ if(c!='\n') a++; if(c=='\n') lines++; if(c==' '||c=='\n'||c=='\t') { fin.get(c); a++; if((c>='a'&&c<='z')||(c>='A'&&c<='Z')) { words++; } } } cout<<"字符数:"<<a<<endl; cout<<"单词数:"<<words<<endl; cout<<"行数:"<<lines<<endl; fin.close(); return 0; }