前言:前面完成一个小项目完成一个建议的行程管理项目。要求c语言完成,学习了好长时间的c++,突然觉得不是很好上手,哈哈,写了大概两天左右,这个代码结构比较清晰,分享如下。
目录
数据结构:存储信息 可以用数组(动态),链表,哈希表,等,我选用最简单的动态数组,通过malloc分配数组的内存后进行赋值,在其获取相应的信息。
其中包括人员信息部分,增删改查相关信息并更新到文件当中。此部分我查询了很多代码,比如删除某一条信息,都是从文件中读取到动态数组(或者链表)当中,删除后又重新写回文件当中,我感觉代价特别高,就用的文件指针,fseek和ftell定位到文件的相应位置,直接删除,或更新信息。不过理解起来更麻烦一些。
站点信息:包括增加删除和查询站点。这个实现起来没有什么难度,注意加入相同的站点信息时,拒绝加入,这样效果更好。
行程信息:增加行程信息和查询。
仔细考虑了一下加入行程信息需要调用系统时间函数,查询了一些相关库函数之后,也将其加入。总体难度不是特别高,我把代码放在这供大家学习,并且指正。Peace!
代码部分
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>//系统时间头文件
#define BASE_STATION_FILE "基站信息.txt"
#define PERSON_FILE "人员信息.txt"
#define TRAVEL_Info_FILE "行程信息.txt"
#pragma warning(disable:4996)
FILE* p;//文件指针
const int Leap[12] = { 31,29,31,30,31,30,31,31,30,31,30,31 };//闰年
const int Ordinary[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };//平年
//获取当前日期
struct Date//日期信息,年月日
{
int year, month, day;
};
Date GetDate();
struct Person//人原信息姓名,性别,电话
{
char name[20]; //姓名
char sex[20]; //性别
char tel[20]; //电话号码
};
struct Base//基站信息
{
char Basic[20];
};
struct TravelInfo
{
char basic[10]; //基站信息
Person p; //人员信息
Date day; //登记日期
};
//展示主菜单
void ShowMainMenu();
//展示子菜单1
void ShowSubMenu1();
//展示子菜单2
void ShowSubMenu2();
//展示子菜单3
void ShowSubMenu3();
//辅助函数统计当前信息个数
//统计有多少信息choice1人员信息 2基站信息 3形成信息,没写完
int CountInfo(int choice);
bool IsLeapYear(int year);
int CountDay(Date d);
bool IsOver15(Date d);
//获取第i条信息
Person GetPersonInfo(int i);
//增加人员信息
void AddPersonInfo();
//删除人员信息
void DelPersonInfo();
//修改人员信息
void ModPersonInfo();
//展示人员信息
void ShowPersonInfo();
//增,删,改,查基站信息
bool IsMatch(const char *a);
Base* DynamicArray(int size);
void AddBaseStation();
void DelBaseStation();//删除基站信息时,提示删除则删除行程信息
void ShowBaseStation();
//增加,查询行程信息
void AddTravelInfo();
void ShowTravelInfo();
//主函数,调用函数
int main()
{
ShowMainMenu();
//cout<<IsMatch("基站17");
//AddTravelInfo();
//AddPersonInfo();
return 0;
}
void ShowMainMenu()
{
int choice;
while (true)//循环输出主菜单
{
system("cls");
printf("*******************************欢迎来到行程卡管理系统!*******************************");
printf("\n\n");
printf("\t\t ----------------------------------------------------\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| 1. 人 员 信 息 |\n");
printf("\t\t| |\n");
printf("\t\t| 2. 站 点 信 息 |\n");
printf("\t\t| |\n");
printf("\t\t| 3. 行 程 信 息 |\n");
printf("\t\t| |\n");
printf("\t\t| 0.退 出 |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t ----------------------------------------------------\n");
printf("请根据选项输入您的选择: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
ShowSubMenu1();
break;
case 2:
ShowSubMenu2();
break;
case 3:
ShowSubMenu3();
break;
case 0://退出
printf("欢迎下次再次使用!");
exit(0);
default://输入错误
printf("输入有误,请重新输入");
system("pause");
break;
}
}
}
void ShowSubMenu1()//人员信息操作
{
int choice;
while (true)//循环输出主菜单
{
system("cls");
printf("*******************************欢迎来到人员管理界面!*******************************");
printf("\n\n");
printf("\t\t ----------------------------------------------------\n");
printf("\t\t| |\n");
printf("\t\t| 1. 增 加 人 员 |\n");
printf("\t\t| |\n");
printf("\t\t| 2. 删 除 人 员 |\n");
printf("\t\t| |\n");
printf("\t\t| 3. 修 改 人 员 |\n");
printf("\t\t| |\n");
printf("\t\t| 4. 查 询 人 员 |\n");
printf("\t\t| |\n");
printf("\t\t| 0. 返回上一级 |\n");
printf("\t\t| |\n");
printf("\t\t ----------------------------------------------------\n");
printf("请根据选项输入您的选择: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
AddPersonInfo();
break;
case 2:
DelPersonInfo();
printf("\n删除成功!");
system("pause");
break;
case 3:
ModPersonInfo();
break;
case 4:
ShowPersonInfo();
system("pause");
break;
case 0://退出
ShowMainMenu();
break;
default://输入错误
printf("输入有误,请重新输入");
system("pause");
system("cls");
break;
}
}
}
void ShowSubMenu2()//站点信息
{
int choice;
while (true)//循环输出主菜单
{
system("cls");
printf("*******************************欢迎来到站点管理界面!*******************************");
printf("\n\n");
printf("\t\t ----------------------------------------------------\n");
printf("\t\t| |\n");
printf("\t\t| 1. 增 加 站 点 |\n");
printf("\t\t| |\n");
printf("\t\t| 2. 删 除 站 点 |\n");
printf("\t\t| |\n");
printf("\t\t| 3. 查 询 站 点 |\n");
printf("\t\t| |\n");
printf("\t\t| 0. 返回上一级 |\n");
printf("\t\t| |\n");
printf("\t\t ----------------------------------------------------\n");
printf("请根据选项输入您的选择: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
AddBaseStation();
system("pause");
break;
case 2:
DelBaseStation();
system("pause");
break;
case 3:
ShowBaseStation();
system("pause");
break;
case 0://退出
ShowMainMenu();
break;
default://输入错误
printf("输入有误,请重新输入");
system("pause");
system("cls");
break;
}
}
}
void ShowSubMenu3()
{
int choice;
while (true)//循环输出主菜单
{
system("cls");
printf("*******************************欢迎来到行程管理界面!*******************************");
printf("\n\n");
printf("\t\t ----------------------------------------------------\n");
printf("\t\t| |\n");
printf("\t\t| 1. 增 加 行 程 |\n");
printf("\t\t| |\n");
printf("\t\t| 2. 查 询 行 程 |\n");
printf("\t\t| |\n");
printf("\t\t| 0. 返回上一级 |\n");
printf("\t\t| |\n");
printf("\t\t ----------------------------------------------------\n");
printf("请根据选项输入您的选择: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
AddTravelInfo();
break;
case 2:
ShowTravelInfo();
break;
case 0://退出
ShowMainMenu();
break;
default://输入错误
printf("输入有误,请重新输入");
system("pause");
system("cls");
break;
}
}
}
//可以获得系统日期
Date GetDate()
{
Date d;
time_t t;
struct tm* p;
time(&t);
p = gmtime(&t);
d.year = p->tm_year + 1900;//获取当前年
d.month = p->tm_mon + 1;//获取月信息
d.day = p->tm_mday;//获取日信息
return d;
}
//获取第i条信息
Person GetPersonInfo(int i)
{
Person a;
p = fopen(PERSON_FILE, "r");
fscanf(p, "%s %s %s", &a.name, &a.sex, &a.tel);
int num = 1;
while (fscanf(p, "%s %s %s", &a.name, &a.sex, &a.tel) != EOF)
{
if (num == i)
{
break;
}
//cout << "第" << num << "条为:" << "姓名为:" << a.name << " 性别为:" << a.sex << " 电话为:" << a.tel << endl;
num++;
}
fclose(p);
return a;
}
//统计信息个数
int CountInfo(int choice)
{
FILE* fp;
int num = 0;
if (choice == 1)//人员信息,统计当前存储人个数
{
p = fopen(PERSON_FILE, "r");
Person a;
if (!p)
{
printf("错误!");
exit(0);
}
fscanf(p, "%s %s %s", &a.name, &a.sex, &a.tel);
while (fscanf(p, "%s %s %s", &a.name, &a.sex, &a.tel) != EOF)
{
num++;
}
fclose(p);
}
else if (choice == 2)
{
char base[10];
p = fopen(BASE_STATION_FILE, "r");
if (!p)
{
printf("当前文件打开失败!\n");
exit(0);
}
fscanf(p, "%s", base);
while (fscanf(p, "%s", base) != EOF)
{
//cout << "第" << num << "个: " << base << endl;
num++;
}
fclose(p);
}
else if (choice == 3)
{
p = fopen(TRAVEL_Info_FILE, "r");
if (!p)
{
printf("当前文件打开失败!\n");
exit(0);
}
//cout << "当前文件指针的位置:" << ftell(p) << endl;
TravelInfo t;
fscanf(p, "%s\t\t%s\t\t%s\t\t%s\t\t%d\t\t%d\t\t%d\n", t.basic, t.p.name, t.p.sex, t.p.tel, &t.day.year, &t.day.month, &t.day.day);
while (fscanf(p, "%s\t\t%s\t\t%s\t\t%s\t\t%d\t\t%d\t\t%d\n", t.basic, t.p.name, t.p.sex, t.p.tel, &t.day.year, &t.day.month, &t.day.day) != EOF)
{
num++;
}
num--;
fclose(p);
}
return num;
}
bool IsLeapYear(int year)//闰年
{
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
return true;
return false;
}
int CountDay(Date d)
{
int num = 0;
if (IsLeapYear(d.year) == 1)//闰年用Leap计算
{
for (int i = 0; i < d.month - 1; i++)
{
num += Leap[i];
}
}
else//平年
{
for (int i = 0; i < d.month - 1; i++)
{
num += Ordinary[i];
}
}
num += d.day;
return num;
}
//添加人员信息
void AddPersonInfo()
{
p = fopen(PERSON_FILE, "a+");//追加方式写数据
if (p==NULL)
{
printf( "添加文件打开失败!");
}
Person a;
printf("请输入待增加姓名:");
scanf("%s", a.name);
printf("请输入性别:");
scanf("%s", a.sex);
printf("请输入电话:");
scanf("%s", a.tel);
fprintf(p, "%s\t%s\t%s\n", a.name, a.sex, a.tel);
fclose(p);
printf("添加人员成功!");
system("pause");
}
//删除人员信息
void DelPersonInfo()
{
int sum=CountInfo(1);
//cout << "sum=" << sum << endl;
if (sum == 0)
{
printf("当前无人员信息,无法删除!");
system("pause");
return;
}
ShowPersonInfo();
int d = 0;
printf("请输入要删除第几条信息:");
scanf("%d", &d);
if (d <= 0 || d > sum)//输入错误,显示问题
{
printf("输入错误!");
system("pause");
return;
}
Person b = GetPersonInfo(d);
//cout << "姓名为:" << b.name << " 性别为:" << b.sex << " 电话为:" << b.tel << endl;
p = fopen(PERSON_FILE, "r+");
if (!p)
{
printf("打开失败!");
exit(0);
}
Person a;
//cout << "初始位置:" << ftell(p) << endl;
fscanf(p, "%s %s %s", &a.name, &a.sex, &a.tel);
while (fscanf(p, "%s %s %s", &a.name, &a.sex, &a.tel) != EOF)
{
int num = strlen(b.name) + strlen(b.sex) + strlen(b.tel)+2;
if (strcmp(a.name, b.name)==0 &&strcmp(a.sex, b.sex)==0&& strcmp(a.tel, b.tel)==0)//找到信息
{
fseek(p, -num, SEEK_CUR);//修正指针位置
for (int i = 0; i < num; i++)
{
fprintf(p, "%s", " ");
}
fclose(p);
return;
}
}
fclose(p);
system("pause");
}
//修改人员信息
void ModPersonInfo()
{
int sum = CountInfo(1);
if (sum == 0)
{
printf("当前无人员信息,无法删除!");
system("pause");
return;
}
ShowPersonInfo();
int d = 0;
printf("请输入要删除第几条信息:");
scanf("%d", &d);
if (d <= 0 || d > sum)//输入错误,显示问题
{
printf("输入错误!");
system("pause");
return;
}
Person b = GetPersonInfo(d);
p = fopen(PERSON_FILE, "r+");
if (!p)
{
printf("打开失败!");
exit(0);
}
Person a;
fscanf(p, "%s %s %s", &a.name, &a.sex, &a.tel);
while (fscanf(p, "%s %s %s", &a.name, &a.sex, &a.tel) != EOF)
{
int num = strlen(b.name) + strlen(b.sex) + strlen(b.tel) + 2;
if (strcmp(a.name, b.name) == 0 && strcmp(a.sex, b.sex) == 0 && strcmp(a.tel, b.tel) == 0)//找到信息
{
fseek(p, -num, SEEK_CUR);//修正指针位置
for (int i = 0; i < num; i++)
{
fprintf(p, "%c", ' ');
}
fclose(p);
}
}
p = fopen(PERSON_FILE, "a+");
printf("请输入修改后的姓名:");
scanf("%s", a.name);
printf("请输入性别:");
scanf("%s", a.sex);
printf("请输入电话:");
scanf("%s", a.tel);
fprintf(p, "%s\t%s\t%s\n", a.name, a.sex, a.tel);
fclose(p);
printf("修改成功!");
system("pause");
}
//展示人员信息
void ShowPersonInfo()
{
if (CountInfo(1) == 0)
{
printf("当前无人员信息!");
return;
}
p = fopen(PERSON_FILE, "r");
Person a;
if (!p)
{
//cout << "无法打开人员信息文件!" << endl;
printf("无法打开人员信息文件!\n");
exit(0);
}
fscanf(p, "%s %s %s", &a.name, &a.sex, &a.tel);
int num = 1;
while (fscanf(p, "%s %s %s", &a.name, &a.sex, &a.tel) != EOF)
{
printf("第%d条为: 姓名:%s 性别:%s 电话:%s\n", num, a.name, a.sex, a.tel);
//cout << "第" << num << "条为:" << "姓名为:" << a.name << " 性别为:" << a.sex << " 电话为:" << a.tel << endl;
num++;
}
fclose(p);
}
//增,删,改,查基站信息
bool IsMatch(const char * a)
{
int sum = CountInfo(2);
if (sum == 0) return false;
Base* Arr = DynamicArray(sum);
for (int i = 0; i < sum; i++)
{
if (strcmp(Arr[i].Basic, a) == 0)
{
return true;
}
}
return false;
}
Base* DynamicArray(int size)
{
static Base* arr = (Base*)malloc(size * sizeof(Base));
p = fopen(BASE_STATION_FILE, "r");
if (!p)
{
printf("打开失败!");
system("pause");
}
fscanf(p, "%s", arr[0].Basic);
int i = 0;
while (fscanf(p, "%s", arr[i].Basic) != EOF)
{
i++;
}
fclose(p);
return arr;
}
void AddBaseStation()
{
int sum = CountInfo(2);
//cout << "当前基站信息的个数:"<<sum << endl;
ShowBaseStation();
char base[20];
printf("请输入您要加入基站的名字:");
scanf("%s", base);//判断和前面是否重复
if (IsMatch(base))
{
printf("不能输入相同的基站名!");
fclose(p);
system("pause");
return;
}
p = fopen(BASE_STATION_FILE, "a+");
fprintf(p, "%s\n", base);
printf("添加基站成功!");
fclose(p);
}
void DelBaseStation()
{
int sum = CountInfo(2);
if (sum == 0)
{
printf("当前基站数为0!无法删除!");
return;
}
ShowBaseStation();
int d = 0;
printf("您要删除第几条信息:");
scanf("%d", &d);
if (d <= 0 || d > sum)
{
printf("您的输入有误!");
return;
}
Base* Arr = DynamicArray(sum);
for (int i =d; i < sum; i++)
{
strcpy(Arr[i-1].Basic ,Arr[i].Basic);
}
sum--;
p = fopen(BASE_STATION_FILE, "w");
fprintf(p, "%s\n", "基站名");
for (int i = 0; i < sum; i++)
{
fprintf(p,"%s\n", Arr[i].Basic);
}
fclose(p);
printf("删除成功!!");
system("pause");
}
void ShowBaseStation()
{
int sum = CountInfo(2);
if (sum == 0)
{
printf("当前无基站信息!");
system("pause");
}
p = fopen(BASE_STATION_FILE, "r");
if (!p)
{
printf("文件打开失败!");
return;
}
char base[20];
fscanf(p, "%s", base);
int num=1;
while (fscanf(p, "%s", base) != EOF)
{
printf("第%d条基站名:%s\n",num, base);
num++;
}
fclose(p);
}
//增加行程信息
void AddTravelInfo()
{
ShowBaseStation();
FILE* px;
px= fopen(TRAVEL_Info_FILE, "a+");
if (px==NULL)
{
printf("添加文件打开失败!");
}
TravelInfo t;
printf("请输入基站信息:");
scanf("%s", t.basic);
if (IsMatch(t.basic) == 0)//不存在基站
{
printf("基站名信息输入错误,退出添加!");
system("pause");
return;
}
printf( "请输入姓名:");
scanf("%s", t.p.name);
printf("请输入性别:输入1 男/输入2 女\n");
int choice = 0;
if (choice == 1)
{
strcpy(t.p.sex ,"男");
}
else if (choice == 2)
{
strcpy(t.p.sex, "女");
}
else
{
printf("输入错误,退出添加!");
system("pause");
return;
}
printf( "请输入电话:");
scanf("%s", t.p.tel);
Date nowdate = GetDate();
t.day.year = nowdate.year;
t.day.month = nowdate.month;
t.day.day = nowdate.day;
//printf("%s\t\t%s\t\t%s\t\t%s\t\t%d\t\t%d\t\t%d\n", t.basic, t.p.name,
// t.p.sex, t.p.tel, t.day.year, t.day.month, t.day.day);
fprintf(px, "%s\t\t%s\t\t%s\t\t%s\t\t%d\t\t%d\t\t%d\n", t.basic, t.p.name,
t.p.sex,t.p.tel, t.day.year, t.day.month, t.day.day);
fclose(px);
printf("添加到文件中成功!");
system("pause");
}
void ShowTravelInfo()
{
int choice = 0;
printf("输入1则全部查询,输入2则根据电话查询!!");
scanf("%d", &choice);
p = fopen(TRAVEL_Info_FILE, "r");
if(!p)
{
printf("打开失败!");
system("pause");
return;
}
TravelInfo t;
if (choice == 1)
{
char tem[20];
fscanf(p, "%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\n", t.basic, t.p.name, t.p.sex, t.p.tel, tem,tem,tem);
int num = 1;
while (fscanf(p, "%s\t\t%s\t\t%s\t\t%s\t\t%d\t\t%d\t\t%d\n", t.basic, t.p.name, t.p.sex, t.p.tel, &t.day.year, &t.day.month, &t.day.day) != EOF)
{
/*cout << "第" << num << "条信息为 基站名:" << t.basic << " 姓名:"
<< t.p.name << " 性别:" << t.p.sex << " 电话:" << t.p.tel
<< " 年:" << t.day.year << " 月:" << t.day.month << " 日:" << t.day.day << endl;*/
printf("第%d条 基站名:%s 姓名:%s 性别:%s 电话:%s 登记日期:%d-%d-%d\n", num,t.basic, t.p.name, t.p.sex, t.p.tel, t.day.year, t.day.month, t.day.day);
num++;
}
}
else if(choice == 2)
{
char phone[20];
printf("请输入电话号码:");
scanf("%s", phone);
char tem[20];
fscanf(p, "%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\n", t.basic, t.p.name, t.p.sex, t.p.tel, tem, tem, tem);
int num = 1;
while (fscanf(p, "%s\t\t%s\t\t%s\t\t%s\t\t%d\t\t%d\t\t%d\n", t.basic, t.p.name, t.p.sex, t.p.tel, &t.day.year, &t.day.month, &t.day.day) != EOF)
{
if (strcmp(phone, t.p.tel) == 0)
{
printf("第%d条 基站名:%s 姓名:%s 性别:%s 电话:%s 登记日期:%d-%d-%d\n", num, t.basic, t.p.name, t.p.sex, t.p.tel, t.day.year, t.day.month, t.day.day);
num++;
}
}
if (num == 1)
{
printf("未查询到相关信息!");
system("pause");
return;
}
}
else
{
printf("输入错误!");
system("pause");
return;
}
fclose(p);
system("pause");
}
配置文件部分
需要在代码相同的文件目录下配置一下这几个文件,来保证代码成功运行。
基站信息.txt
基站名
基站1
基站2
基站3
基站4
基站5
人员信息.txt
姓名 性别 电话
张三 男 15628271711
李四 男 14558729988
王红 女 12345667777
行程信息.txt
基站名 等级姓名 性别 电话 日期年 月 日
基站3 李四 男 12721721721 2022 5 20
基站8 张飞 男 1261721821 2022 5 21
同时要把文件格式编码改成ANSII,这样能保证代码正常并且不会乱码!好了
结果展示
例如查询基站信息
增加行程信息
在文件中存入了信息,和当前的日期。
这个其实还有很多可优化空间,待探索优化,欢迎提出一些建议。