一、实验目的
- 理解流的概念
- 熟悉流类库中常用的类及成员函数用法
- 熟悉 I/O 格式控制方法,掌握常用格式控制
- 了解文件 I/O,掌握文件 I/O 基本用法
二、实验准备
结合第 11 章教材、课件,复习/学习如下内容:
- 基础知识
- 流是什么?如何理解?
- C++中 I/O 是通过什么来实现的?
- 常用 I/O 流类的继承/派生层次关系
- 预定义标准流对象 cin, cout, cerr, clog
- C++中格式化 I/O 方法
- 文件 I/O 方法及常用成员函数
三、实验内容
- 基础练习
- 教材习题 11-7
- 教材习题 11-3
- 教材习题 11-4
- 应用练习
- 已知有班级名单文件 list.txt(见实验 7 附件包)。编写一个应用程序实现随机抽点
5 位同学,在屏幕上显示结果,同时,也将结果写入文件 roll.txt。- 编写程序实现题目基本功能要求。(必做)
- (******选做******)
对①中实现的基本功能进行完善、扩充,使得这个点名应用程序更灵活、更方便。比如:- 从键盘输入班级文件名,支持对不同班级的点名操作;
- 从键盘输入用于保存点名结果的文件名。更灵活地,自动获取当前系统日期作为文件名,比如 20180612.txt。(如果希望更细粒度,文件名可以到小时和分钟这一层级);
- 随机抽点人数不固定,通过键盘按键控制何时抽点结束;
- 通过菜单及程序的函数模块划分,或类的设计与实现,做成一个更完善的应用,等等。
- 统计英文文本文件字符数、单词数、行数,文件名由键盘输入。
- 编写 C++程序实现题目基本功能要求。(必做)
- ******选做******
- 提供菜单,由用户选择统计内容;
- 思考当文本内容数量级偏大,①处已实现的程序能否胜任,实现快速统计?在算法和处理逻辑上是否存在进一步改进的部分?
- 已知有班级名单文件 list.txt(见实验 7 附件包)。编写一个应用程序实现随机抽点
四、实验步骤
4.1 基础练习
4.1.1 11-7
注释:
#include <iostream> using namespace ::std; int main() { ios_base::fmtflags original_flags = cout.flags(); //保存cout参数设置 cout<< 812<<'|'; cout.setf(ios_base::left,ios_base::adjustfield); //设置cout的对齐方式为左对齐 cout.width(10); //将cout宽度改为10 cout<< 813 << 815 << '/n'; cout.unsetf(ios_base::adjustfield); //取消cout对齐方式的设置 cout.precision(2);// 设置浮点数输出的精度值 cout.setf(ios_base::uppercase|ios_base::scientific); //设置浮点数的显示参数 cout << 831.0 ; cout.flags(original_flags); //恢复cout原参数设置 return 0; }
Screenshot:
4.1.2 11-3
Code:
#include<bits/stdc++.h> using namespace std; int main(){ ofstream fout("test1.txt"); fout<<"已成功写入文件!"; fout.close(); return 0; }
演示:
4.1.3 11-4
Code:
#include<bits/stdc++.h> using namespace std; int main(){ ifstream fin("test1.txt"); string tmp; getline(fin,tmp); cout<<tmp; fin.close(); system("pause"); return 0; }
演示:
4.2 应用练习
4.2.1
①:必做部分:
控制台窗口运行结果:#include<bits/stdc++.h> #define rap(a,b) for(int a=0;a<b;++a) using namespace std; struct stu{ int num; string stuid,name,cls; }tmp; ostream &operator <<(ostream &o,const stu &tmp){ o<<tmp.num<<" "<<tmp.stuid<<" "<<tmp.name<<" "<<tmp.cls<<endl; return o; } ifstream fin; int main(){ ifstream fin("list.txt"); vector<stu>a; while(fin>>tmp.num>>tmp.stuid>>tmp.name>>tmp.cls){ a.push_back(tmp); } //cout<<a.size(); fin.close(); ofstream fout("roll.txt"); srand((unsigned)time(NULL)); rap(i,5){ int tmp2=rand()%a.size(); cout<<a[tmp2]; fout<<a[tmp2]; } fout.close(); return 0; }
运行文件夹及文件截图:
②:选做部分
实现功能:通过输入班级序号选择班级进行点名,通过ENTER键控制点名数量,通过时间或用户输入的字符串保存文件:
Code:#include<bits/stdc++.h> #define rap(a,b) for(int a=0;a<b;++a) using namespace std; struct stu{ int num; string stuid,name,cls; }tmp; ostream &operator <<(ostream &o,const stu &tmp){ o<<tmp.num<<" "<<tmp.stuid<<" "<<tmp.name<<" "<<tmp.cls<<endl; return o; } int cmp(const stu &a,const stu &b){ return a.cls>b.cls; } void callbyclass(vector<stu>a,vector<stu>*res){ int sz=a.size(); sort(a.begin(),a.end(),cmp); vector<int>clsidx; string tmp=a[0].cls; clsidx.push_back(0); rap(i,sz){ if(a[i].cls!=tmp){ clsidx.push_back(i); tmp=a[i].cls; } } clsidx.push_back(sz); cout<<"Class:"<<endl; rap(i,clsidx.size()-1)cout<<i+1<<" : "<<a[clsidx[i]].cls<<endl; cout<<"Please Choose Class num to call student"<<endl; int idx; cin>>idx; while(idx>clsidx.size()){ cout<<"Wrong Class number, plz choose again!"<<endl; cin>>idx; } getchar(); do{ int t=rand()%(clsidx[idx]-clsidx[idx-1]); cout<<a[t+clsidx[idx-1]]; res->push_back(a[t+clsidx[idx-1]]); }while(getchar()=='\n'); } int main(){ time_t t = time(0); ifstream fin("list.txt"); vector<stu>a; while(fin>>tmp.num>>tmp.stuid>>tmp.name>>tmp.cls){ a.push_back(tmp); } fin.close(); srand((unsigned)time(NULL)); vector<stu>res; callbyclass(a,&res); cout<<"Save by time enter 1, by your desired string enter 2.\n"; int tmp; cin>>tmp; if(tmp==1) { char ch[64]; strftime(ch, sizeof(ch), "%Y%m%d%H%M%S.txt", localtime(&t)); ofstream fout(ch); rap(i,res.size())fout<<res[i]; fout.close(); } else if(tmp==2){ string n; cout<<"\nPlz enter your filename:"<<endl; cin>>n; ofstream fout(n.c_str()); rap(i,res.size())fout<<res[i]; fout.close(); } return 0; }
演示效果如下:
4.2.2
① 必做部分:
算法思路:利用getline函数读入每一行,每一行得到的 string.size() 即为每行字符数量,利用 strtok 分割文本得到单词数。
Code:#include<bits/stdc++.h> using namespace std; const char de[]={'"',',',' ','.','\0','!','?','-','(',')','#','/',':'}; int main(){ cout<<"Please Enter filname:\n"; string filename; cin>>filename; ifstream fin(filename.c_str()); string line; long long linenum=0,chnum=0,wordnum=0; while(getline(fin,line)){ char *tmp=new char[line.length()+1]; strcpy(tmp,line.c_str()); char *tmp2; tmp2=strtok(tmp,de); if(tmp2!="")wordnum++; while((tmp2=strtok(NULL,de)))wordnum++; linenum++; chnum+=line.size(); } cout<<"行数:"<<linenum<<" 字符数:"<<chnum<<" 单词数:"<<wordnum; fin.close(); return 0; }
- 测试文件1(233.txt):
测试文件2 (bible.txt):