程序大部分来源于学长的博客:
菜鸡的短学期作业 公交线路管理系统 - Xunflash的小站
作者在一些细节的地方做了总结和修改。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>//win头文件
/*-------------------------------------------课本上没有学过的函数-------------------------------------*/
//fflush() //用于清空文件缓冲区的函数
//system("cls"); //清屏函数
//Sleep(500); //windows函数,表示间隔500ms
//system("color F0"); //给终端调色为白底黑字便于操作
//system("pause"); //暂停程序的执行
/*-------------------------------------------函数声明区----------------------------------------------*/
int menu(); //菜单函数
int search(int cin); //查询站点,线路编号最大值函数
void back(); //返回函数
void stationmax(); //判断站点是否已满函数
void linemax(); //判断线路是否已满函数
void read(); //读取文件函数
void save(); //保存数据到Dat文件中
void stationmsg(); //显示站点信息函数
void addstation(); //添加站点函数
void deletestation(); //删除站点函数
void changestation(); //修改站点名字函数
void addline(); //添加线路函数
void changeline(); //修改线路函数
void searchline(); //查找所有站点函数
/*-------------------------------------------结构体定义区--------------------------------------------*/
char str[200];
struct Stations //创建站点结构体
{
int num;//站点编号
char stname[20];//站点名称
} station[500];
struct Lines //创建线路结构体
{
int num;
int endnum;
char liname[20];
char endname[20];
struct Stations sta[500];
} line[100];
/*---------------------------------------------函数定义区----------------------------------------------*/
void back() { //返回函数
char a;
printf("\n 输入回车返回....\n");
fflush(stdin); //fflush()用于清空文件缓冲区
a = getchar();
system("cls"); /*清屏*/
}
int search(int cin) { //搜索函数
int i = 0;
if (cin == 1)//read()函数中已经将两个数组的首元素的值定为1
for (i = 0; i < 500; i++) //求下一个空站点的位置
if (station[i].num == 0)
break;
if (cin == 2)
for (i = 0; i < 100; i++) //求下一个空线路位置
if (line[i].num == 0 && *line[i].liname == '\0')
break;
return i;//返回搜索后的结果,第一次返回的时候是i=1
}
void stationmax() { //站点达到最大值时提示
if (station[499].num != 0) {
printf(" 线路数量已经超出最大值\n");
back();
menu();
}
}
void linemax() { //线路达到最大值时提示
if (line[99].num != 0) {
printf(" 线路数量已经超出最大值\n");
back();
menu();
}
}
void read() { //读取文件函数
int i;
station[0].num = 1;//第一个站点的编号为1
line[0].num = 1;//第一条线路的编号为1
FILE* fp1, * fp2;
//FILE*是一个结构体
//定义两个结构体指针
printf(" 正在尝试读取数据...\n\n");
if ((fp1 = fopen("1.dat", "r+")) == NULL) {
//打开并可读写文件,如果找不到就创建
//"r+":可读/写数据,该文件必须先存在,否则打开失败
printf(" 检测到未创建数据文件1,正在创建中...\n");
Sleep(300);
fp1 = fopen("1.dat", "w+");
//"w+":可读/写数据,打开一个新建的文件,先向该文件写数据,然后可读取该文件中的数据
}
else {
fp1 = fopen("1.dat", "r+");
for (i = 0; i < 100; i++)
if (fread(&station[i], sizeof(struct Stations), 1, fp1) != 1)
break;
//读取站点数据存放的内存的指针,一次读取一个结构体的字节数,一次读取一次,fp1是读取文件的指针
//读到没有站点数据的结构体数组时停下
}
if ((fp2 = fopen("2.dat", "r+")) == NULL) {
printf(" 检测到未创建数据文件2,正在创建中...\n");
Sleep(300);
fp2 = fopen("2.dat", "w+");
}
else {
fp2 = fopen("2.dat", "r+");
for (i = 0; i < 500; i++)
if (fread(&line[i], sizeof(struct Lines), 1, fp2) != 1)
break;
}
fclose(fp1);//关闭文件fp1
fclose(fp2);
Sleep(500);
printf(" 读取数据成功!");
Sleep(500);
system("cls");//清屏
return;
}
void save() { //保存内存数据到结构体函数
int i;
FILE* fp1 = NULL, * fp2 = NULL;
printf(" 正在保存数据...\n");
if ((fp1 = fopen("1.dat", "w+")) == NULL) {
printf(" 检测到数据文件1丢失,正在创建中...\n");
fp1 = fopen("1.dat", "w+");
}
fp1 = fopen("1.dat", "w+");
for (i = 0; station[i].num != 0 && i < 100; i++)
if (fwrite(&station[i], sizeof(struct Stations), 1, fp1) != 1)
break;
if ((fp2 = fopen("2.dat", "w+")) == NULL) {
printf(" 检测到数据文件2丢失,正在创建中...\n");
fp2 = fopen("2.dat", "w+");
}
fp2 = fopen("2.dat", "w+");
for (i = 0; line[i].num != 0 && i < 500; i++)
if (fwrite(&line[i], sizeof(struct Lines), 1, fp2) != 1)
break;
printf(" 保存数据成功!\n");
fclose(fp1);
fclose(fp2);
return;
}
void stationmsg() { //显示站点信息函数
printf("\n 公交线路管理系统\n");
printf("\n 全部站点信息如下:\n");
int i;
for (i = 0; i < 500; i++) {//遍历结构体数组,当结构体中的编号和站点名称都有内容时输出
if (station[i].num != 0 && *station[i].stname != '\0') {
printf(" %d %s\n", station[i].num, station[i].stname);
}
}
}
void addstation() { //添加站点函数
printf("\n 公交线路管理系统\n");
printf(" 新增公交站点\n");
int i, flag = 0;
char name[1000];//先定义一个新的字符串
i = search(1);//搜索下一个空站点的位置
stationmax();//判断站点数量是否达到最大值
printf(" 请输入站点名称:");
scanf("%s", &name);
if (strlen(name) > 20) {
printf(" 站点名字过长(不能超过20个字符)!\n");
return;//返回调用函数的地方
}
else {
strcpy((station[i-1].stname), name);//复制字符串
station[i].num = i + 1;//站点编号从1开始
save();
}
}
void deletestation() { //删除站点函数
printf("\n 公交线路管理系统\n\n");
printf(" 删除公交站点\n\n");
int m, n, r = 0;
n = search(2); //搜索下一个空线路
m = search(1); //搜索下一个空站点
for (int j = 0; j < 500; j++) {
if (station[j].num != 0 && *station[j].stname != '\0') {
printf(" %d %s\n", station[j].num, station[j].stname);
}
}//遍历打印已有的站点
printf("\n 请输入站点编号:");
char cin[1000];
int i, num;
if (scanf("%d", &num)) {
for (i = 0; i < 500; i++) {
if (station[i].num == num && *station[i].stname != '\0') {
break;//当站点编号等于输入数字时跳出循环
}
}
if (num == 0 ||station[num - 1].num == 0 || *station[num - 1].stname == '\0') {
printf("\n 找不到该站点\n");//当站点编号等于零,站点还未加入,站点的名称为空时
return;
}
else {
printf("\n 确认要删除该站点吗?(Y/N)");
scanf("%s", &cin);
if (*cin == 'y' || *cin == 'Y') {
for (int p = 0; p < n; p++) { //外循环是线路
for (int q = 0; q < m; q++) { //内循环是站点
if (!strcmp(line[p].sta[q].stname, station[num-1].stname)) {
for (int l = q; l < 500; l++) {
if (l != 499) {
line[p].sta[l].num = line[p].sta[l + 1].num;
if(line[p].sta[l].num!=0)
line[p].sta[l].num--;
strcpy(line[p].sta[l].stname, line[p].sta[l + 1].stname);
}
else {
line[p].sta[l].num = 0;
strcpy(line[p].sta[l].stname, "\0");
}
}
if (!strcmp(line[p].endname, station[num - 1].stname)) {
strcpy(line[p].endname, "\0");
line[p].num = 0;
}
}
}
}
for (int p = i; p < 499; p++) {
if (station[p + 1].num > 1)
station[p + 1].num--;
station[p] = station[p + 1];
}
}
save();
return;
}
}
else {
printf("\n 请输入正确的编号!\n");
return;
}
}
void changestation() { //修改站点函数
printf("\n 公交线路管理系统\n\n");
printf(" 修改公交站点\n");
for (int j = 0; j < 500; j++) {
if (station[j].num != 0 && *station[j].stname != '\0') {
printf(" %d %s\n", station[j].num, station[j].stname);
}
}
char name[1000];
int i, num, flag = 0; //创建输入临时变量
printf(" 请输入需要修改的站点编号:");
if (scanf("%d", &num)) {
fflush(stdin);
for (i = 0; i < 500; i++) {
if (station[i].num == num && *station[i].stname != '\0') {
flag++; //符合条件时进行标记
break;
}
}
if (flag == 1) {
printf("\n 原站点名称为:%s\n 请输入修改后的站点名称:", station[i].stname);
scanf("%s", &name);
if (strlen(name) > 20) { //判断输入字符长度
printf(" 站点名字过长(不能超过20个字符)!\n");
return;
}
else {
strcpy(station[i].stname, name); //复制临时输入站点名称到结构体中
printf("\n 修改完毕!\n");
}
}
else {
printf(" 找不到该编号所对应的站点\n");
return;
}
}
else {
printf("\n 请输入正确的编号!\n");
return;
}
save();
}
void addline() { //增加线路函数
printf("\n 公交线路管理系统\n\n");
printf(" 新增公交线路\n\n");
char name[1000]; //临时输入数据
int i, j, flag1 = 0, flag2 = 0, start, end; //定义临时变量和起点站终点站编号
linemax();//判断线路是否已满
i = search(2);//搜索下一个空线路
printf(" 请输入线路名称:\n ");
scanf("%s", &name);
if (strlen(name) > 20) {
printf(" 线路名字过长(不能超过20个字符)!\n");
return;
}
else {
strcpy(line[i - 1].liname, name);
line[i].num = i + 1;
}
printf(" 请输入起点站编号\n ");
if (scanf("%d", &start))
for (j = 0; j < 500; j++) {
if (start != 0 && start == station[j].num && strcmp(station[j].stname, "\0")) {
//站点编号匹配,站点名称不为空时
line[i - 1].sta[0].num = start;
strcpy(line[i - 1].sta[0].stname, station[start - 1].stname);
flag1++;//确认起点站添加成功
}
}
else {
printf("\n 请输入正确的编号!\n");
return;
}
while (flag1 == 0) {
printf(" 找不到该站点,请重新输入:");
if (scanf("%d", &start))
for (j = 0; j < 500; j++) {
if (start != 0 && start == station[j].num && strcmp(station[j].stname, "\0")) {
line[i - 1].sta[0].num = start;
strcpy(line[i - 1].sta[0].stname, station[start].stname);
flag1++;
}
}
else {
printf("\n 请输入正确的编号!\n");
return;
}
}
printf(" 请输入终点站编号\n ");
if (scanf("%d", &end))
for (j = 0; j < 500; j++) {
if (end != 0 && end == station[j].num && strcmp(station[j].stname,"\0")) {
line[i - 1].endnum = end;
strcpy(line[i - 1].endname, station[end - 1].stname);
flag2++;
}
}
else {
printf("\n 请输入正确的编号!\n");
return;
}
while (flag2 == 0) {
printf(" 找不到该站点,请重新输入:");
if (scanf("%d", &end))
for (j = 0; j < 500; j++) {
if (end != 0 && end == station[j].num && strcmp(station[j].stname, "\0")) {
line[i].endnum = end;
strcpy(line[i].endname, station[end - 1].stname);
flag2++;
}
}
else {
printf("\n 请输入正确的编号!\n");
return;
}
}
save();
}
void changeline() { //修改线路函数
printf("\n 公交线路管理系统\n");
printf("\n 修改 公交线路\n");
int num1 = 0;
char cin[1000]; //键盘输入的字符
int i, j, num, flag = 0, cin1, cin2, m; //创建输入临时变量
j = search(1);
if (*line[0].liname == '\0') {
printf(" 请先添加线路\n");
return;
}
for (int i = 0; i < 100; i++) {
if (line[i].num != 0 && *line[i].liname != '\0') {
if (line[i].sta[0].num == 0 || line[i].endnum == 0) {
printf("\n %d该线路起点站或终点站被删除,请先修改线路", line[i].num);
}
else {
printf(" %d:%s路:起点站:%d %s -> ", line[i].num, line[i].liname, line[i].sta[0].num, line[i].sta[0].stname);
for (int j = 1; j < 500; j++) {
if (*line[i].sta[j].stname != '\0')
printf("%d %s -> ", line[i].sta[j].num, line[i].sta[j].stname);
}
printf("终点站:%d %s\n\n", line[i].endnum, line[i].endname);
}
}
}
printf(" 请输入需要修改的线路编号:");
if (scanf("%d", &num))
for (i = 0; i < 100; i++) {
if (line[i].num == num && *line[i].liname != '\0') {
flag++; //符合条件时进行标记
break;
}
}
else {
printf("\n 请输入正确的编号!\n");
return;
}
while (1) {
if (flag == 0) {
printf(" 找不到该编号所对应的线路\n");
back();
printf("\n 公交线路管理系统\n");
printf("\n 修改 公交线路\n");
for (int i = 0; i < 100; i++) {
if (line[i].num != 0 && *line[i].liname != '\0') {
if (line[i].sta[0].num == 0 || line[i].endnum == 0) {
printf("\n %d该线路起点站或终点站被删除,请先修改线路", line[i].num);
}
else {
printf(" %d:%s路:起点站:%d %s -> ", line[i].num, line[i].liname, line[i].sta[0].num, line[i].sta[0].stname);
for (int j = 1; j < 500; j++) {
if (*line[i].sta[j].stname != '\0')
printf("%d %s -> ", line[i].sta[j].num, line[i].sta[j].stname);
}
printf("终点站:%d %s\n\n", line[i].endnum, line[i].endname);
}
}
}
printf(" 请输入需要修改的线路编号:");
if (scanf("%d", &num))
for (i = 0; i < 100; i++) {
if (line[i].num == num && *line[i].liname != '\0') {
flag++; //符合条件时进行标记
break;
}
}
else {
printf("\n 请输入正确的编号!\n");
return;
}
system("cls");
continue;
}
system("cls");
printf(" 正在修改的线路为:\n\n");
printf(" %d:%s路 :起点站:%d %s -> ", line[i].num, line[i].liname, line[i].sta[0].num, line[i].sta[0].stname);
for (int j = 1; j < 500; j++) {
if (*line[i].sta[j].stname != '\0')
printf("%d %s -> ", line[i].sta[j].num, line[i].sta[j].stname);
}
printf("终点站:%d %s\n\n", line[i].endnum, line[i].endname);
printf(" *******************************\n");
printf(" * 修改公交线路菜单 *\n");
printf(" * *\n");
printf(" * 1.修改线路名称 *\n");
printf(" * 2.修改线路起点站 *\n");
printf(" * 3.修改线路终点站 *\n");
printf(" * 4.新增线路途径站 *\n");
printf(" * 5.删除公交线路 *\n");
printf(" * 6. 返回 *\n");
printf(" *******************************\n");
printf(" 请输入操作编号:");
fflush(stdin);
num1 = 0;
if (scanf("%d", &num1))
while (num1 <= 0 || num1 >= 7) {
printf(" 请输入正确的数字:");
if (!scanf("%d", &num1)) {
printf("\n 请输入正确的编号!\n");
return;
}
}
else {
printf("\n 请输入正确的编号!\n");
return;
}
switch (num1) {
case 1: {
printf("\n 原线路名称为:%s\n 请输入修改后的线路名称:", line[i].liname);
scanf("%s", &cin);
if (strlen(cin) > 20) { //判断输入字符长度
printf(" 线路名字过长(不能超过20个字符)!\n");
back();
continue;
}
else {
strcpy(line[i].liname, cin); //复制临时输入站点名称到结构体中
printf("\n 修改完毕!\n");
}
save();
Sleep(500);
system("cls");
}break;
case 2: {
printf("\n 原线路起点站为:%d %s\n 请输入修改后的起点站编号:", line[i].sta[0].num, line[i].sta[0].stname);
if (scanf("%d", &cin1)) {
if (cin1 >= j || cin1 <= 0) {
printf(" 找不到对应站点!\n");
back();
continue;
}
else {
line[i].sta[0].num = cin1; //复制临时输入站点名称到结构体中
strcpy(line[i].sta[0].stname, station[cin1-1].stname);
printf("\n 修改完毕!\n");
}
save();
Sleep(500);
system("cls");
}
else {
printf("\n 请输入正确的编号!\n");
back();
continue;
}
}break;
case 3: {
printf("\n 原线路终点站为:%d %s\n 请输入修改后的终点站编号:", line[i].endnum, line[i].endname);
if (scanf("%d", &cin1)) {
if (cin1 >= j || cin1 <= 0) {
printf(" 找不到对应站点!\n");
back();
continue;
}
else {
line[i].endnum = cin1; //复制临时输入站点名称到结构体中
strcpy(line[i].endname, station[cin1-1].stname);
printf("\n 修改完毕!\n");
}
save();
Sleep(500);
system("cls");
}
else {
printf("\n 请输入正确的编号!\n");
back();
continue;
}
}break;
case 4: {
printf("\n 请输入途径站编号:");
if (scanf("%d", &cin1)) {
if (cin1 > j || cin1 <= 0) {
printf(" 找不到对应站点!\n");
back();
continue;
}
else {
printf("\n 请输入途径站插入位置\n");
printf("(想插在第几站后面,就填第几站):");
if (scanf("%d", &cin2))
for (m = 0; m < 500; m++) {
if (line[i].sta[m].num == 0) {
break;
}
}
else {
printf("\n 请输入正确的编号!\n");
back();
continue;
}
if (cin2 > m || cin2 < 1) {
printf(" 位置输入有误,请检查后再试");
back();
continue;
}
else {
for (int q = m; q >= cin2; q--) {
line[i].sta[q + 1].num = line[i].sta[q].num;
strcpy(line[i].sta[q + 1].stname, line[i].sta[q].stname);
}
line[i].sta[cin2].num = cin1;
strcpy(line[i].sta[cin2].stname, station[cin1 - 1].stname);
printf("\n 修改完毕!\n");
}
}
}
else {
printf("\n 请输入正确的编号!\n");
back();
continue;
}
save();
Sleep(500);
system("cls");
}break;
case 5: {
printf("\n 确认要删除该线路吗?(Y/N)");
scanf("%s", &cin);
if (*cin == 'y' || *cin == 'Y' ) {
for (int p = i; p < 99; p++) {
if (line[p + 1].num > 1)
line[p + 1].num--;//后面线路的编号全部减1
line[p] = line[p + 1];
}
}
save();
Sleep(500);
system("cls");
return;
}break;
case 6: return;
system("pause");
}
}
}
void searchline() { //查询线路函数
printf("\n 公交线路管理系统\n");
printf("\n 查询 公交线路\n");
int i, cin;
for (i = 0; i < 100; i++) {
if (line[i].num != 0 && *line[i].liname != '\0') {
if (line[i].sta[0].num == 0 || line[i].endnum == 0) {
printf("\n %d该线路起点站或终点站被删除,请先修改线路", line[i].num);
}
else {
printf(" %d:%s路:起点站:%d %s -> ", line[i].num, line[i].liname, line[i].sta[0].num, line[i].sta[0].stname);
for (int j = 1; j < 500; j++) {
if (*line[i].sta[j].stname != '\0')
printf("%d %s -> ", line[i].sta[j].num, line[i].sta[j].stname);
}
printf("终点站:%d %s\n\n", line[i].endnum, line[i].endname);
}
}
}
printf("\n 请输入需要查询的线路编号:");
if (scanf("%d", &cin))
if (*line[cin - 1].liname != '\0') {
if (line[cin - 1].sta[0].num == 0 || line[cin - 1].endnum == 0) {
printf("\n %d该线路起点站或终点站被删除,请先修改线路", line[cin - 1].num);
}
else {
printf(" %d:%s路:起点站:%d %s -> ", line[cin - 1].num, line[cin - 1].liname, line[cin - 1].sta[0].num, line[cin - 1].sta[0].stname);
for (int j = 1; j < 500; j++) {
if (line[cin - 1].sta[j].num != 0 && *line[cin - 1].sta[j - 1].stname != '\0')
printf("%d %s -> ", line[cin - 1].sta[j].num, line[cin - 1].sta[j].stname);
}
printf("终点站:%d %s\n", line[cin - 1].endnum, line[cin - 1].endname);
}
}
else {
printf("\n 查询不到该编号对应的线路");
}
else {
printf("\n 请输入正确的编号!\n");
return;
}
}
int menu() { //显示菜单函数 //菜单函数
int num1 = 0;
printf(" *******************************\n");
printf(" * 欢迎使用 *\n");
printf(" * 公交线路管理系统 *\n");
printf(" * *\n");
printf(" * 1.显示全部站点信息 *\n");
printf(" * 2.新增公交站点 *\n");
printf(" * 3.删除公交站点 *\n");
printf(" * 4.修改公交站点 *\n");
printf(" * *\n");
printf(" * 5.新增公交线路 *\n");
printf(" * 6.调整公交线路 *\n");
printf(" * 7.查询公交线路 *\n");
printf(" * 8.退出 *\n");
printf(" *******************************\n");
printf(" 请输入操作编号:");
if (scanf("%d", &num1)) {
system("cls");
switch (num1) {//用switch结构来确定下一步操作
case 1: stationmsg(); return 1; break;//1. 显示全部站点信息
case 2: addstation(); return 1; break;//2.新增公交站点
case 3: deletestation(); return 1; break;//3.删除公交站点
case 4: changestation(); return 1; break;//4.修改公交站点
case 5: addline(); return 1; break;//5.新增公交线路
case 6: changeline(); return 1; break;//6.修改公交线路
case 7: searchline(); return 1; break;//7. 查询公交线路
case 8: return 2; break;//8.退出该管理系统
default: printf(" 请输入正确的数字。\n");
return 1;//当输入的不是1-8时
break;
}
}
else {
printf("\n 请输入正确的编号!\n");
return 1;//当输入的不是数字时
}
system("pause");
return 0;
}
/*----------------------------------------------主函数------------------------------------------------*/
int main() {
system("color F0"); //给终端调色为白底黑字便于操作
read();//读取数据dat文件
fflush(stdin);//清空文件缓冲区
int flag = 1;//先定义一个flag变量,之后要根据flag的值来进行相应的操作
flag = menu(); //循环结构,使menu能够实现自动清屏返回上一级
while (flag == 1) {
back();
flag = menu();
}
if (flag == 2) return 0; //退出程序
system("pause");
return 0;
}
/*-----------------------------------------------结束------------------------------------------------*/