【实验目的】
掌握运算符重载的基本方法。
掌握标准输入输出的使用及格式控制方法。
掌握磁盘文件(如二进制文件、文本文件)的输入输出的方法。
【实验内容】
1.编写程序,重载运算符“<<”和“>>”,使用户能直接输入和输出固定电话的号码。电话号码以如下形式输入和输出: (027)xxxxxxxx
重载输入输出流进行类对象的输入与输出,固定电话号码类包含区号以及手机号string数据类型
Code:
#include
#include
using namespace std;
class Tel {
private:
string _Area;
string _Tel;
public:
Tel() {}
//返回is引用 保证只有一个输入流对象
friend istream& operator>>(istream &in, Tel &tel) {
cout << "请输入正确的电话号码:";
string Num;
in >> Num;
int rightBrack = Num.find(")");
tel._Area = Num.substr(1, rightBrack);
tel._Tel = Num.substr(rightBrack + 1, Num.length());
return in;
}
friend ostream& operator<<(ostream &out, Tel &tel) {
//输出带括号的电话号码
cout << "输出电话号码为:";
out << "(" + tel._Area + ")" + tel._Tel << endl;
return out;
}
};
void main() {
Tel tel;
cin >> tel;
cout << tel;
return;
}
2.编写一个程序,实现以下功能:
(1)输入一系列的学生成绩(包括学号、姓名、成绩等数据)存放在文件stud.dat中。
(2)从stud.dat文件中读出这些数据并显示出来。
(3)在stud.dat文件中按姓名进行查询,如输入“李”,则将所有姓李的学生的数据都显示出来。所编写的程序运行结果示例如下:
选择(1:输入数据 2:输出数据 3:按姓名查找数据 其他退出):1
输入数据
学生人数:5
第1个学生(学号 姓名 成绩):1001 张三 89
第2个学生(学号 姓名 成绩):1002 李四 78
第3个学生(学号 姓名 成绩):1003 王五 92
第4个学生(学号 姓名 成绩):1004 李沅芷 88
第5个学生(学号 姓名 成绩):1005 赵六 56
选择(1:输入数据 2:输出数据 3:按姓名查找数据 其他退出):2
输出数据
学号 姓名 成绩
1001 张三 89
1002 李四 78
1003 王五 92
1004 李沅芷 88
1005 赵六 56
选择(1:输入数据 2:输出数据 3:按姓名查找数据 其他退出):3
输入姓名:李
输出匹配的结果:
学号 姓名 成绩
1002 李四 78
1004 李沅芷 88
选择(1:输入数据 2:输出数据 3:按姓名查找数据 其他退出):3
输入姓名:李四
输出匹配的结果:
学号 姓名 成绩
1002 李四 78
选择(1:输入数据 2:输出数据 3:按姓名查找数据 其他退出):0
【提示】在重载运算符“<<”和“>>”时,不能将其定义为类的成员函数,只能定义为类的友元函数。
Code:
#include
#include
#include
using namespace std;
char name[13];
class Student {
private:
char Number[13];
char Name[13];
double Grade;
static int i;
public:
friend istream& operator>>(istream &in, Student *stuIn) { //先写入变量 再写入文件
ofstream binFile;//写入文件
binFile.open("D:\\stud.dat");
for (int i = 0; i <5; i++){
cout << "第" << i+1 << "个学生(学号 姓名 成绩):";//写入变量
cin >> stuIn[i].Number;
cin >> stuIn[i].Name;
cin >> stuIn[i].Grade;
binFile.write((char*)&stuIn[i], sizeof(Student));//写入文件
}
binFile.close();
return in;
}
friend ostream& operator<<(ostream &out, Student &stuOut) {
ifstream inFile;
inFile.open("D:\\stud.dat");
cout << "学号 姓名 成绩" << endl;
for (int j = 1; j <=5; j++) {
inFile.read((char*)&stuOut, sizeof(Student)); //先从文件写入变量
out<<stuOut.Number << " " << stuOut.Name << " " << stuOut.Grade << endl;
}
inFile.close();
return out;
}
char* Getnumber() { return Number; }
char* Getname() { return Name; }
double Getgrade() { return Grade; }
};
int Student::i = 0;
void main() {
Student *stuIn=new Student[5];
Student stuOut;
int choice,flag=0;
while (true){
cout << "1.输入数据" << endl;
cout << "2.输出数据" << endl;
cout<<"3.按姓名查找数据"<<endl;
cout << "0.退出" << endl;
cin >> choice;
switch (choice)
{
case 1:
cout << "学生人数:5" << endl;
cin >> stuIn; //输入并保存
flag = 1;
break;
case 2:
if (flag == 0) {
cout << "请先输入学生信息再进行查询" << endl;
break;
}
cout << stuOut;//输出
break;
case 3:
if (flag==0){
cout << "请先输入学生信息再进行查询" << endl;
break;
}
cout << "输入姓名:";
char nameIn[20];
cin >> nameIn;
if (strstr(stuIn[1].Getname(), nameIn)!=0 || strcmp(stuIn[1].Getname(), nameIn) == 0) {
cout<<"hhh"<<endl;
}
cout << "输出匹配结果:" << endl;
cout << "学号 姓名 成绩" << endl;
for (int i = 0; i < 5; i++){
if (strstr(stuIn[i].Getname(),nameIn)!=0 || strcmp(stuIn[i].Getname(),nameIn)==0){
cout << stuIn[i].Getnumber() << " " << stuIn[i].Getname() << " " << stuIn[i].Getgrade() << endl;
}
}
break;
case 0:
exit(0);
break;
}
}
return;
}
3.已知
void Sort(int a[],int size);
void Sort(double a[],int size);
是一个函数模板的两个实例,其功能是将数组a中的前size个元素按从小到大顺序排列。试设计这个函数模板,并构建main主函数和数据测试函数模板。
(比较简单 但写的时候突然想到了堆排序 就试着回忆着用推排序 知道思路但是写的时候还是遇到了问题
老师的ppt上有这道实验题答案 用冒泡排序写的哈哈哈哈)
堆排序讲解 非常透彻!!
另外,代码和实验要求不是很符合,权当复习下堆排序了。
#include
using namespace std;
#define LeftChild(i) (2*(i)+1)
template<typename T>
//元素下沉(从编号为i的元素开始调整)
void PercDown(T a[], int i, int N) {
int child;
T tmp;
for (tmp = a[i]; LeftChild(i) < N; i = child) {
child = LeftChild(i);
if (child != N - 1 && a[child + 1] > a[child]) {
child++;
}
if (a[i] < a[child]) {
tmp = a[i];
a[i] = a[child];
a[child] = tmp;
}
}
}
template<typename T>
//数组a的前size个元素进行排序
void Sort(T a[], int size) {
T end[5];
for (int i = 0; i < size; i++) {
end[i] = a[i];
}
//1.创建一个大根堆 (从第一个非叶子节点开始)
for (int i = size/2-1; i >=0; i--){
PercDown(end, i, size);
}
//2.不断调整大根堆,使其到达有序 (交换size-1次)
for (int i = size-1; i>0; i--){
T flag=end[i];
end[i] = end[0];
end[0] = flag;
PercDown(end, 0, i);
}
for (int i = 0; i < size; i++) {
a[i] = end[i] ;
}
}
void main() {
int a[7] = { 1,3,4,2,5,7,6 };
double b[7] = { 1.1,3.1,4.1,2.1,5.1,7.1,6.1};
Sort(a, 5);
Sort(b, 5);
cout << "a数组排序后前5个元素";
for (int i = 0; i < 5; i++){
cout << a[i] << " ";
}
cout << endl;
cout << "b数组排序后前5个元素";
for (int i = 0; i < 5; i++){
cout << b[i] << " ";
}
}
4.设有如下的类声明:
…
试将此类声明改为类模板声明,使得数据成员data1和data2可以是任何类型。,并构建main主函数和数据测试类模板。(比较简单)
#include
using namespace std;
//类模板:声明一个类时将实现这个类所需要的数据成员的类型、成员函数的参数类型
// 或返回值的类型参数化
template<typename T1,typename T2>
class Test
{
public:
void SetData1(T1 val) { data1 = val; }
void SetData2(T2 val) { data2 = val: }
T1 GetData1() { return data1; }
T2 GetData2() { return data2; }
private:
T1 data1;
T2 data2;
};
void main() {
Test<int,double> t1;
int x = 5;
double y = 5.5
t1.SetData1(x);
t1.SetData2(y);
cout << "data1 = " << t1.GetData1() << endl;
cout << "data2 = " << t1.GetData2() << endl;
}
和老师发的参考做的不一样…