目录
Step4:改进input和output函数完成结构体数组的输入。
四、致谢:
写在前面:
哈哈哈~ sgq周五又留新作业啦~踢到我,你算是踢到棉花啦~(笔芯.gif)
今天又学了一天的程序设计呢~
爷爷奶奶可高兴了~
给了我最爱吃的大笔豆~
一、题目:
建立一个学生结构类型,包括:学生的学号,姓名,性别,三门成绩。
要求实现以下功能:
input()函数输入若干学生信息,学生人数由主函数提供,输入的信息保存到数组中。
output()输出函数,输出学生的信息。
check()实现输入学号可以查询学生信息。
二、思路:
1.关于结构体:
首先由题目可知,我们需要自定义一个结构体类型student,定义好元素类型(学号,姓名为字符型数组,性别为字符型,三门成绩为双精度浮点型)
(1)学号要使用字符型,因为通常情况下学号超过了长整型的范围大小。
(2)数组的长度要适当长些,输入的时候可以随时使用回车键终止输入,但过短可能会出现“\0”没有地方存储的情况,进而出现数组溢出或学号和姓名连在一起输出的情况。
报错原因2由tjl倾情提供
#include<iostream>
using namespace std;
struct student {
char number[11];
char name[50];
};
int main()
{
struct student s;
cin >> s.number;
cin >> s.name;
cout << s.number << " ";
cout << s.name;
}
上面就是一个比较简单的输入输出程序,我们想要输入的学号为11位,如果把数组的长度正好定义为11的话,后面的姓名也会跟在一起输出,如左图所示:
而如果把number[11]的长度稍微调多一些,就可以顺利输出,如右图所示:
2.关于数组:
一个学生就是一个结构体,我们想要输入多个学生,就需要用到结构体数组,因此我们要在主调函数中定义一个结构体数组。
3.关于函数:
输入函数选择结构体指针型函数,返回一个结构体数组。
输出函数可以通过指针遍历进行输出,再加const关键字修饰,防止其指向的值被篡改。
4.关于思想:
至于编程的思想,我们依旧采用模块化的思想,将整个问题拆分成多个小模块,逐步解决实现,最后完成整个程序。
三、程序:
Step1:在主函数内完成单一简单结构体的输入输出。
这个应该是结构体很入门的知识了,这里不再赘述,参见上方程序即可。
Step2:编写input函数完成单一简单结构体的输入。
因为函数并不能改变形参的值,因此我们选择通过返回值在主函数为结构体赋值。由于我们将输出单独编写成了一个函数放在了主函数的外面,因此我们需要在主函数定义结构体时将其初始化。
程序如下:
#include<iostream>
using namespace std;
struct student {
char number[20];
char name[50];
};
struct student input()//输入函数
{
struct student s;//定义一个结构体s
cout << "请输入学号:";
cin >> s.number;
cout << "请输入姓名:";
cin >> s.name;
return s;//将结构体s返回到主函数中
}
int main()
{
struct student s = { 0 };
s=input();
//在主函数中为结构体赋值,将被调函数中的s赋值给主调函数中的s
//注意:两个s并不相同!被调函数中的s调用后即焚!!
cout << "number:"<<s.number<<" name:"<< s.name;
}
Step3:编写output函数完成单一简单结构体的输出。
由于我们需要用到指针,所以函数的形参需要取结构体s的地址(&s)传入到output中,再用*s作为实参进行遍历输出。同时在实参前加const修饰代表其为指向常量的指针。结构体指针运算符为"->",灵活运用它就可以利用指针完成结构体的输出。
程序如下:
#include<iostream>
using namespace std;
struct student {
char number[20];
char name[50];
};
struct student input()输入函数
{
struct student s;
cout << "请输入学号:";
cin >> s.number;
cout << "请输入姓名:";
cin >> s.name;
return s;
}
void output(const struct student* s)//输出函数
{
cout << "number:" << s->number << " name:" << s->name << endl;
//"->"运算符可以使指针s指向结构体的特定元素
return;
}
int main()
{
struct student s = { 0 };
s=input();
output(&s);
}
Step1.2.3的输出均相同,如下图所示:
Step4:改进input和output函数完成结构体数组的输入。
这一步,类比整型和整型数组即可,在主函数的结构体定义时加上长度,循环调用input函数即可完成数组的输入。结构体数组的输出,我们将每个结构体的首地址传给输出函数后循环调用即可,程序如下:
#include<iostream>
using namespace std;
struct student {
char number[20];
char name[50];
};
struct student input()
{
struct student s;
cout << "请输入学号:";
cin >> s.number;
cout << "请输入姓名:";
cin >> s.name;
return s;
}
void output(const struct student* s)
//这里收到的就是s[i]的地址,从这个地址开始输出
{
cout << "number:" << s->number << " name:" << s->name << endl;
return;
}
int main()
{
int n;
cout << "请输入要录入的学生个数:";
cin >> n;
struct student s[9999] = { 0 };//不要忘记长度为定长
for (int i = 0; i < n; i++)
s[i] = input();
for (int i = 0; i < n; i++)
output(&s[i]);//取下标为i的结构体的首地址
}
输出如下图所示:
Step5:编写check函数完成结构体的查找。
由于要查找的字符串为字符型,因此我想到之前字符串操作系统的strcmp,这个是一个字符串的比较的函数,如果相同就返回0,否则返回非零值,原文链接挂在下面了:
所以我选择调用这个函数在结构体数组中对学号进行字符串的比较,如果相等就输出,如果遍历结束仍未找到就输出提示。
具体思路为:将结构体数组,输入的字符数组学号和结构体数组的长度作为形参传入check函数中,外层for循环用于数组的遍历,这个的思路依然和找素数的思路极为相似,需要注意的是,这里的循环判断条件为i<=n,因为我希望i==n的时候如果还没有找到学号相同的学生的话输出提示语。内层if语句用来判断是否完整遍历了结构体数组,再内层的if语句用来判断学生的学号与输入的学号是否相等,如果相等则输出返回主函数,否则执行空语句进入下一次循环。
程序如下图:
#include<iostream>
#include<string>
using namespace std;
struct student {
char number[20];
char name[50];
};
struct student input()
{
struct student s;
cout << "请输入学号:";
cin >> s.number;
cout << "请输入姓名:";
cin >> s.name;
return s;
}
void output(const struct student* s)
{
cout << "number:" << s->number << " name:" << s->name << endl;
return;
}
void search(struct student s[], char num[], int n)
{
for (int i = 0; i <= n; i++)//遍历结构体数组
{
if (i < n)//如果没遍历完
{
if (strcmp(num, s[i].number) != 0)//如果不相等的话
;//执行空语句,进入下一次循环
else//如果两个字符串相等的话
{
cout << s[i].number << " " << s[i].name;//输出
break;//跳出循环
}
}
else//遍历完了还没有跳出循环
cout << "没找着" << endl;//输出提示语
}
return;
}
int main()
{
int n;
char num[20];
cout << "请输入要录入的学生个数:";
cin >> n;
struct student s[9999] = { 0 };
for (int i = 0; i < n; i++)
s[i] = input();
for (int i = 0; i < n; i++)
output(&s[i]);
cout << "请输入要查找的学号:";
cin >> num;
search(s, num, n);//传入结构体数组,字符串数组,学生数量
}
代码执行如下:
Step6:优化输出
程序的框架到这里大概已经成型啦!(printf("撒花"))~这之后我们只需要完善结构体的类型,优化我们的输出与提示,让我们的程序更丝滑就可以啦,完整程序如下:
#include<iostream>
#include<string>
using namespace std;
struct student {
char number[20];
char name[50];
char gender[2];
double C;
double math;
double intro;
};
void print()
{
cout << "请输入要执行的操作:" << endl;
cout << "1.查看学生列表:" << endl;
cout << "2.补录学生信息:" << endl;
cout << "3.学号查找信息" << endl;
cout << "4.退出应用程序" << endl;
}
struct student input()
{
struct student s;
cout << "请输入学号:";
cin >> s.number;
cout << "请输入姓名:";
cin >> s.name;
cout << "请输入性别:";
cin >> s.gender;
cout << "请输入C语言成绩:";
cin >> s.C;
cout << "请输入数学成绩:";
cin >> s.math;
cout << "请输入计概成绩:";
cin >> s.intro;
return s;
}
void output(const struct student* s)
{
cout << "学号:" << s->number << " 姓名" << s->name << " 性别" << s->gender
<< " C语言成绩:" << s->C << " 数学成绩:" << s->math << " 计概成绩:" << s->intro << endl;
return;
}
void search(struct student s[], char num[], int n)
{
for (int i = 0; i <= n; i++)
{
if (i < n)
{
if (strcmp(num, s[i].number) != 0)
;
else
{
output(&s[i]);
break;
}
}
else
cout << "没找着" << endl;
}
return;
}
int main()
{
int n, operate;
char num[20];
cout << "学生信息录入:" << endl;
cout << "请输入要录入的学生个数:";
cin >> n;
struct student s[9999] = { 0 };
for (int i = 0; i < n; i++)
s[i] = input();
while (1)
{
print();
cin >> operate;
switch (operate)
{
case 1:
for (int i = 0; i < n; i++)
output(&s[i]);
break;
case 2:
n++;
s[n-1] = input();
break;
case 3:
cout << "请输入要查找的学号:";
cin >> num;
search(s, num, n);
break;
case 4:
return 0;
}
}
}
四、致谢:
这么严谨的博客怎么能少的了珍贵的致谢环节呢,先感谢一下sgq吧,谢谢她又让我度过了一个充实的周六,从下午打开教材,b站大学,CSDN开始学习再到编程运行调试再到写完这篇博客,整整耗时8个小时^=^。再感谢一下一直陪伴在我身边的各位,你们是我坚持下去的动力(感动.jpg)