【题目】student.txt(GB2312 编码)中存放了 20 个学生信息,包
括:学号、姓名、性别、籍贯、出生日期。这个 20 个同学没有重名
的。编写一个学生信息管理小程序,实现下面的功能:
我们要从一个txt中读取信息,多组学生的信息显然易见要存放在一个结构体数组中。把代码全部放在一个源文件实在太过冗杂,这里我们可以把main函数放在一个源文件,功能实现放在别的源文件中,通过自己写一个头文件进行连接。那么这个结构体的定义就要写在头文件中,不过结构体数组要定义在源文件中并在头文件中声明。一个而多次使用的系统我们可以使用一个do while结构来实现。
cout << "欢迎使用学生管信息管理系统" << endl;
int a;
do
{
menu1();
cin >> a;
switch (a)
{
case 0:
cout << "欢迎下次使用" << endl;
file.close();
break;
case 1:
sexclass(total);
break;
case 2:
monthclass(total);
break;
case 3:
find(total);
break;
case 4:
modify(total);
goto begine;
break;
case 5:
add(total);
goto begine;
break;
case 6:
sort(total);
break;
default:
cout << "输入错误,请重新输入" << endl;
break;
}
} while (a);
读入 student.txt 的学生信息;要读入一个.txt类的文件储存方式为ANSI格式
读入文本文件分为5步
1.引头文件
2.创建流对象
iftream file (ofstream–只写、ifstream–只读、fstream–可读可写.)
3.打开文件(并判断文件是否成功打开)
file.open(“文件路径”,打开方式)
打开方式分为
打开方式 | 对应操作 |
---|---|
ios::in | 为读文件而打开 |
ios::out | 为写文件而打开 |
ios::ate | 文件尾为初始位置 |
ios::app | 追加内容 |
ios::trunc | 重写文件 |
ios::binary | 二进制形式读写 |
注:不同的打开方式配合 | 操作符使用。
4读数据
5关闭文件
//读入文件
fstream file;
file.open("D:\\student.txt", ios::in);
char s[200] = { 0 };
int total = 0;
while (file.getline(s, 200))
{
strcpy(stu[total].number, strtok(s, "\t"));
strcpy(stu[total].name, strtok(NULL, "\t"));
strcpy(stu[total].sex, strtok(NULL, "\t"));
strcpy(stu[total].hometown, strtok(NULL, "\t"));
strcpy(stu[total].date, strtok(NULL, "\t"));
total++;
}
这里将数据先存在了一个char类的数组s之中,然后借用strcpy和strtok函数来实显将数据存在一个结构体数组之中;
这里拿一个total就可以确定学生人数,而且会有妙用
因为数据全拿一个结构体以字符串的形式储存,所以我们因该用strcmp函数来实现比较,然后创建两个变量分别储存男女的数量。
void sexclass(int total)
{
int male = 0;
int female = 0;
int i = 0;
char nan[6] = "男";
char nv[6] = "女";
for (i = 0; i < total; i++)
{
if (strcmp(stu[i].sex, nan)==0)
{
male++;
}
if (strcmp(stu[i].sex, nv) == 0)
{
female++;
}
}
cout << "男生有:" << male << "人" << endl;
cout << "女生有:" << female << "人" << endl;
}
和上面那个差不多,没什么好说的
void monthclass(int total)
{
int i = 0;
int sum = 0;
for (i = 0; i < total; i++)
{
if (stu[i].date[5] == '1' && stu[i].date[6] == '1')
sum++;
}
cout << sum<<endl;
}
其实这里我们可以先把月转换出来
int month[50] = { 0 };
for (j = 0; j < total; j++)
{
int a = 0;
for (a = 5; a < 7; a++)
{
if (stu[j].date[a] != '/')
month[j] = month[j] * 10 + (stu[j].date[a] - '0');
}
}
int day[50] = { 0 };
然后判断哪个月就很随便了
(要求)输入一个姓名,查找 student 文件中是否存在他的信息,如果存
在,输出出他(她)的信息,如果不存在,输出“没有这个同学的信
息”。可以多次查询,每次查询结束询问用户是否继续查询
多次查询这不又do while
这里要注意的是在前面mian函数中输入了一个数据并使用回车在这里若想使用getline必须先”清空“,我们可以使用getchar来清空。
void find(int total)
{
int a = 0;
char mz[10] = {'0'};
do {
cout << "请输入学生姓名"<<endl;
getchar();//将输入的回车换行吸收掉
cin.getline(mz, 11);
int i = 0;
for (i = 0; i < total; i++)
{
if (strcmp(mz, stu[i].name) == 0)
{
cout << stu[i].number << "\t" << stu[i].name << "\t" << stu[i].sex << "\t" << stu[i].hometown << "\t" << stu[i].date << endl;
break;
}
}
if (i == total)
{
cout << "没有这个同学的信息" << endl;
}
cout << "是否继续查找" << endl;
cout << " 1:继续 " << endl;
cout << " 0:停止 " << endl;
cin >> a;
}while (a);
}
宋羽玲同学的生源地录入有误,将她的籍贯改为江苏省,并保存
到 student.txt 文件中
只要将存着宋羽玲信息的数组先找到然后将省会替换就行
void modify(int total)
{
cout << "要修改的学生名字" << endl;
int a = 0;
char mz[10] = { '0' };
getchar();//将输入的回车换行吸收掉
cin.getline(mz, 11);
int i = 0;
for (i = 0; i < total; i++)
{
if (strcmp(mz, stu[i].name) == 0)
{
change(i,total);
break;
}
}
if (i == total)
{
cout << "没有这个同学的信息" << endl;
}
}
void change(int i,int total)
{
cout << "输入要修改的值" << endl;
cin.getline(stu[i].hometown, 10);
save(total);//保存修改后的数据
}
void save(int total)
{
ofstream ofs;
ofs.open("D:\\student.txt", ios::out);
int i = 0;
for (i = 0; i < total; i++)
{
ofs << stu[i].number << "\t";
ofs << stu[i].name << "\t";
ofs << stu[i].sex << "\t";
ofs << stu[i].hometown << "\t";
ofs << stu[i].date << endl;
}
ofs.close();
}
这里改完后的存和读差不多就不多赘述,
值得注意的是这里我希望将数据进行一次更新,也就是重新读一次,这里我们可以使用goto函数,具体见上
在开辟结构体空间时我刻意多创造了一些,然后用total来卡着每次循环的次数。所以这里直接添加然后存一下,并重新读取
void add(int total)
{
int i = total;
cout << "输入学生编号:";
getchar();
cin.getline(stu[i].number, 5);
cout << endl << "输入学生名字:";
cin.getline(stu[i].name, 10);
cout << endl << "输入学生性别:";
cin.getline(stu[i].sex, 6);
cout << endl << "输入学生籍贯:";
cin.getline(stu[i].hometown, 10);
cout << endl << "输入学生出生日期:";
cin.getline(stu[i].date, 12);
save(total + 1);
}
这里我将年月日分别取出,后使用了一种较为暴力的方式进行处理。没有技术含量,希望大佬可以给我一种比较新的写法
void sort(int total)
{
int year[50] = { 0 };
int j;
int sum = 0;
for (j = 0; j < total; j++)
{
int a = 0;
for (a = 0; a < 4; a++)
{
year[j] = year[j] * 10 + (stu[j].date[a] - '0');
}
}
int month[50] = { 0 };
for (j = 0; j < total; j++)
{
int a = 0;
for (a = 5; a < 7; a++)
{
if (stu[j].date[a] != '/')
month[j] = month[j] * 10 + (stu[j].date[a] - '0');
}
}
int day[50] = { 0 };
for (j = 0; j < total; j++)
{
int a = 0;
for (a = 7; a < 10; a++)
{
if (stu[j].date[a] != '/' && stu[j].date[a] != '\0')
day[j] = day[j] * 10 + (stu[j].date[a] - '0');
}
}
int out[50] = { -1 };
for (int a = 2003; a < 2005; a++)
{
for (int b = 1; b < 13; b++)
{
for (int c = 1; c < 32; c++)
{
for (int i = 0; i < total; i++)
{
if (year[i] == a && month[i] == b && day[i] == c)
{
cout << stu[i].number << "\t";
cout << stu[i].name << "\t";
cout << stu[i].sex << "\t";
cout << stu[i].hometown << "\t";
cout << stu[i].date << "\n";
sum++;
}
}
}
}
}
//cout << sum<
}
完整代码
存学生的txt