高级语言程序设计II
实验报告三
姓名:许恺
学号:2014011329
日期:2015年5月25日
1. 实验目的
通过在c++中使用文本文件和二进制文件的读写比较两者的区别和优劣,同时锻炼c++的编程能力。
2. 设计思路
用一个基类随机生成并记录学生对象的数据,再使用两个子类实现两种形式的读写,在主函数中进行文件大小和生成时间的记录,在读文件的函数中进行时间控制,最后把学生信息打印出来。
3. 代码实现
主函数部分:
// c++报告3.cpp: 定义控制台应用程序的入口点
//
#include "stdafx.h"
#include <iostream>
#include <string> //字符串头文件
#include "student0.h"
#include "student1.h"
#include "student2.h"
#include <fstream>
#include <iomanip>
#include <time.h>
using namespace std;
int main(int argc, _TCHAR* argv[])
{
int a,n,e,s[N];
fstream fp1,fp2;
cout<<"How many student?"<<endl;
cin>>n; //输入学生人数
student0* stu=new student0[n]; //定义放学生信息的对象
student1 stu1; //用来读写文件的对象
student2 stu2;
fp1.open("D:\\aaa.txt",ios::out); //文本文件打开
fp2.open("D:\\bbb.dat",ios::out|ios::binary); //二进制文件打开
if(!fp2||!fp1) //防打不开
cout<<"File open error!\n";
for(a=0;a<n;a++) //进入函数次
s[a]=stu[a].input(a); //输入组数据
clock_t start,end; //建立时间起点和终点
double time;
start=clock(); //开始计时
for(a=0;a<n;a++ ) //进入函数数次,文本文件写入
stu1.write1(a,fp1,stu);
end=clock(); //结束计时
time=double(end-start)/CLOCKS_PER_SEC;
cout<<"The time of writing .txt file="<<time<<endl;
fp1.seekg(0, ios::end); //设置文件指针到文件流的尾部
streampos ps = fp1.tellg(); //读取文件指针的位置得出文件大小
cout << "File size: " << ps << endl;
start=clock(); //二进制的开始计时
for(a=0;a<n;a++ ) //进入函数数次二进制文件写入
stu2.write2(a,fp2,stu);
end=clock(); //二进制的结束计时
time=double(end-start)/CLOCKS_PER_SEC; //算时间time.h中define CLOCKS_PER_SEC 1000
cout<<"The time of writing .dat file="<<time<<endl;
fp2.seekg(0, ios::end); //设置文件指针到文件流的尾部
streampos ps1 = fp2.tellg(); //读取文件指针的位置
cout << "File size: " << ps1 << endl;
fp1.close(); //关闭文件
fp2.close();
fp1.open("d:\\aaa.txt",ios::in); //重新打开两个文件准备读出
fp2.open("d:\\bbb.dat",ios::in|ios::binary);
stu1.output1(fp1,s,n); //读取输出文件
stu2.output2(fp2,s,n); //读取输出文件
fp1.close();
fp2.close();
delete[] stu;
return 0;
}
基类student0.h:
#pragma once
//#include "student2.h"
const int N=10000;
#include <string>
class student0
{
public:
int input(int a); //在公有中的输入函数
int getnum();
char* getname(); //将私有属性用出去的方法让他变成函数return出去
char* getsex();
char* getadd();
private:
int num;
char name[20];
char sex[5];
char address[N];
};
基类student0.cpp:
#include "StdAfx.h"
#include "student0.h"
#include "student2.h"
#include <iostream>
using namespace std;
int student0::input(int a) //输入函数
{
int d,len; //记录长度
char str[100],s[2][5]={"boy","girl"};
num=a+1;
len=1+rand()%9;
for(d=0;d<len;d++)
str[d]='a'+rand()%26;
str[d]='\0';
strcpy(name,str);
strcpy(sex,s[rand()%2]);
len=10+rand()%10;
for(d=0;d<len;d++)
str[d]='A'+rand()%26;
str[d]='\0';
strcpy(address,str);
return len;
}
int student0::getnum()
{
return num;
}
char* student0::getname()
{
return name;
}
char* student0::getsex()
{
return sex;
}
char* student0::getadd()
{
return address;
}
文本文件的子类student1.h:
#pragma once
#include "student0.h"
using namespace std;
class student1 :public student0
{
public:
void write1(int a,std::fstream& fp1,student0 *stu); //写入文本文件函数
void output1(std::fstream& fp1,int s[N],int n); //读出到屏幕的函数
};
文本文件的子类student1.cpp:
#include "StdAfx.h"
#include "student0.h"
#include "student1.h"
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <iomanip>//控制输出的头文件
using namespace std;
void student1:: write1(int a,std::fstream& fp1,student0 *stu)
{
fp1<<setw(10)<<setiosflags(ios::left)<<stu[a].getnum(); //输入输出流读写文本文件控制长度和左对齐
fp1<<setw(20)<<setiosflags(ios::left)<<stu[a].getname();
fp1<<setw(5)<<setiosflags(ios::left)<<stu[a].getsex();
fp1<<setw(strlen(stu[a].getadd()))<<stu[a].getadd()<<endl;
}
void student1::output1(std::fstream& fp1,int s[N],int n)
{
int e,a;
char b[30],c[5],d[1000]={0};
clock_t start,end; //建立时间起点和终点
double time;
start=clock();
for(a=0;a<n;a++)
{
fp1>>setw(10)>>e;
//cout<<setw(10)<<setiosflags(ios::left)<<e; //控制输chu10个字符左对齐
fp1>>setw(20)>>b;
//cout<<setw(20)<<setiosflags(ios::left)<<b;
fp1>>setw(5)>>c;
//cout<<setw(5)<<setiosflags(ios::left)<<c;
fp1>>setw(s[a]+1)>>d;
//cout<<setw(s[a])<<setiosflags(ios::left)<<d<<endl;
}
end=clock(); //结束计时
time=double(end-start)/CLOCKS_PER_SEC;
cout<<"The time of reading .txt file="<<time<<endl; //读出所用时间
}
二进制文件的子类student2.h:
#pragma once
#include <string>
#include "student0.h"
using namespace std;
class student2 :public student0
{
public:
void write2(int a,std::fstream& fp2,student0 *stu); //写入二进制文件函数
void output2(std::fstream& fp2,int s[N],int n); //读出输出到屏幕的函数
};
二进制文件的子类student2.cpp:
#include "StdAfx.h"
#include "student2.h"
#include <fstream>
#include <iomanip>
#include <iostream>
#include <time.h>
void student2::write2(int a,std::fstream& fp2,student0 *stu)
{
int num=stu[a].getnum() ; //整形的函数二进制写入要另外用一个变量不知道为啥不然会报错
fp2.write((char*)&num,10);
fp2.write(stu[a].getname(),20);
fp2.write(stu[a].getsex(),5);
fp2.write(stu[a].getadd(),strlen(stu[a].getadd()));
fp2.write("\n",1);
}
void student2::output2(std::fstream& fp2,int s[N],int n)
{
int e,a;
char b[30],c[5];
clock_t start,end; //建立时间起点和终点
double time;
start=clock();
for(a=0;a<n;a++) //二进制读出文件计算时间
{
fp2.read((char*)&e,10);
//cout<<setw(10)<<setiosflags(ios::left)<<e;
fp2.read(b,20);
//cout<<setw(20)<<setiosflags(ios::left)<<b;
fp2.read(c,5);
//cout<<setw(5)<<setiosflags(ios::left)<<c;
char d[N]={0};
fp2.read(d,s[a]+1);
//cout<<setiosflags(ios::left)<<d;
}
end=clock(); //结束计时
time=double(end-start)/CLOCKS_PER_SEC;
cout<<"The time of reading .dat file="<<time<<endl; //读出所用时间
fp2.seekg(0);
for(a=0;a<n;a++) //二进制读出打印文件
{
fp2.read((char*)&e,10);
cout<<setw(10)<<setiosflags(ios::left)<<e;
fp2.read(b,20);
cout<<setw(20)<<setiosflags(ios::left)<<b;
fp2.read(c,5);
cout<<setw(5)<<setiosflags(ios::left)<<c;
char d[N]={0};
fp2.read(d,s[a]+1);
cout<<setiosflags(ios::left)<<d;
}
}
4. 实验结果及分析。
文件记录个数 |
文件类型 |
文件大小(KB) |
写入时间(S) |
写入速度(MB/S) |
读出时间(S) |
读出速度(MB/S) |
|
1000 |
文本文件 |
50.3 |
0.017 |
2.89 |
0.019 |
2.58 |
|
二进制文件 |
49.3 |
0.003 |
16.08 |
0.004 |
12.03 |
|
|
10000 |
文本文件 |
503 |
0.179 |
2.74 |
0.219 |
2.24 |
|
二进制文件 |
493 |
0.027 |
17.83 |
0.04 |
12.03 |
|
分析:
虽然文件大小并没有差很多,但是读写速度真是天壤之别,二进制的太快了,是文本的5,6倍,个人认为可能是因为二进制就是计算机语言,识别更快,而文本的需要再次转换为二进制才能读取,故时间有差异。