作业要求
用Visual Studio 编写一个控制台程序<程序名Members.exe为例>,功能如下:
第一阶段:依次输入姓名,性别,工号,电话,然后即时的显示出来。
第二阶段:把输入信息以下面格式保存在文本中,并且可以增加人员信息并保存:这个阶段程序完成后请存入6名以上同仁信息。
Index 1
Name: xxx
Sex: Male
ID: W00000
Number: 121
第三阶段:查询人员信息:
输入"Members.exe -find Index1","Members.exe -find xxx", "Members.exe -find 121", "Members.exe -find W00000" 均直接显示这个人员的所有信息。
输入"Members.exe -find Male" 即显示出Sex为Male 的所有人信息。
第四阶段:把所有人员信息按照ID的大小排序。并把排序后的结果保存在原文本里。
头文件和全局变量
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<cstring>
#include <iostream>
#include<fstream>
#include<io.h>
int file_exists(const char* filename);
int get_from_txt();
int write_to_txt(int i);
int sort_member();
using namespace std;
struct member {
int index;
char Name[10];
char Sex[8];
char ID[10];
char Number[13];
};
member X[7];
主函数
int main(int nArgc,char *argv[])
{
//定义一个index字符串
char flag[12] = "index";
//用于拼接和保存字符化后的整型变量
char str[12], string[6];
//用于给成员分配index、接收命令行参数、非命令行下的选择操作
int i = 1; char sel[12]; int s;
//判断是否存在成员信息,不存在则进行写入
if (!file_exists("member.txt"))
{
write_to_txt(i);
}
//存在的话则从缓存中读取数据
else
{
get_from_txt();
}
//如果不在命令行运行或未配置参数,则提供可选择的操作
if (nArgc == 1)
{
printf("是否需要排序?如果是请输入1:");
scanf("%d", &s);
if (s == 1)
{
sort_member();
printf("已完成排序,是否需要保存信息?如果是请输入1:");
scanf("%d", &s);
if (s == 1)
{
FILE* fp = fopen("member.txt", "a");
for (int j = 0; j < 7; j++)
{
fprintf(fp, "index %d\nName:%s\nSex:%s\nID:%s\nNumber:%s\n\n", X[j].index, X[j].Name, X[j].Sex, X[j].ID, X[j].Number);
}
printf("信息已经保存,请进行其他操作。\n");
fclose(fp);
}
printf("是否需要显示所有成员信息?如果是请输入1:");
scanf("%d", &s);
if (s == 1)
{
for (int j = 0; j < 7; j++)
{
printf("index %d\nName:%s\nSex:%s\nID:%s\nNumber:%s\n\n", X[j].index, X[j].Name, X[j].Sex, X[j].ID, X[j].Number);
}
}
}
else
{
printf("未对信息进行排序,请进行其他操作。\n");
printf("是否需要显示所有成员信息?如果是请输入1:");
scanf("%d", &s);
if (s == 1)
{
for (int j = 0; j < 7; j++)
{
printf("index %d\nName:%s\nSex:%s\nID:%s\nNumber:%s\n\n", X[j].index, X[j].Name, X[j].Sex, X[j].ID, X[j].Number);
}
}
}
}
//包含程序名在内参数为3个时进行下一步匹配
if (nArgc == 3)
{
//除程序名之外第一个参数为“-find”时进入查询
if (!_stricmp(argv[1], "-find"))
{
//为sel复制第二个参数的地址
strcpy(sel, argv[2]);
for (int j = 0; j < 7; j++)
{
//每次循环都为str分配字符串flag的地址
strcpy(str, flag);
//将成员的index信息转为字符型变量,并存入string
_itoa(X[j].index, string, 10);
//将str与string拼接为index1的形式
strcat_s(str, string);
//或语句匹配成员的每一项信息
if (!_stricmp(str, sel) | !_stricmp(X[j].Sex, sel) | !_stricmp(X[j].ID, sel) | !_stricmp(X[j].Name, sel) | !_stricmp(X[j].Number, sel))
{
printf("index %d\nName:%s\nSex:%s\nID:%s\nNumber:%s\n\n", X[j].index, X[j].Name, X[j].Sex, X[j].ID, X[j].Number);
}
}
//相关信息已全部列出
cout << "All The Relevant Information Has Been Listed.";
}
//如果第一个参数不是“-find”,则提示参数错误
else
{
cout << "Parameters Error.";
}
}
//包含程序名在内如果参数只有两个,且参数与“-find”相符
else if (nArgc == 2 && !_stricmp(argv[1], "-find"))
{
//提示参数不足
cout << "Insufficient Parameters.";
}
//包含程序名在内如果参数只有两个,且参数与“-find”不符
else if (nArgc == 2 && _stricmp(argv[1], "-find") != 0)
{
//提示参数错误
cout << "Parameters Error.";
}
//包含程序名在内参数大于3时
else if (nArgc > 3)
{
//提示参数过多
cout << "Too Many Parameters.";
};
}
几个函数
//用于判断文件是否存在,不存在则返回0
int file_exists(const char* filename)
{
return (_access(filename, 0) == 0);
}
//当成员信息不存在时,则为结构体写入信息,并创建一个保存信息的文本
int write_to_txt(int i)
{
printf("请依次输入姓名、性别、工号、电话号码,以空格键分隔:\n");
//首先输入第一个成员信息
X[0].index = 1;
scanf("%s %s %s %s", X[0].Name, X[0].Sex, X[0].ID, X[0].Number);
printf("index %d\nName:%s\nSex:%s\nID:%s\nNumber:%s\n\n", X[0].index, X[0].Name, X[0].Sex, X[0].ID, X[0].Number);
//初始化X[6]的index值,用于结束后面的while循环
X[6].index = 0;
//创建文本
FILE* fp1 = fopen("member.txt", "wt");
//创建一个副本,方便读取信息
FILE* fp2 = fopen("member_temp.txt", "wt");
//写第一个成员信息
fprintf(fp1, "index %d\nName:%s\nSex:%s\nID:%s\nNumber:%s\n\n", X[0].index, X[0].Name, X[0].Sex, X[0].ID, X[0].Number);
//副本中只写入信息而不附加说明
fprintf(fp2, "%d\n%s\n%s\n%s\n%s\n", X[0].index, X[0].Name, X[0].Sex, X[0].ID, X[0].Number);
//一直到第7个成员信息被写入,结束循环
while (X[6].index == 0)
{
X[i].index = i + 1;
printf("请依次输入姓名、性别、工号、电话号码,以空格键分隔:\n");
scanf("%s %s %s %s", X[i].Name, X[i].Sex, X[i].ID, X[i].Number);
printf("index %d\nName:%s\nSex:%s\nID:%s\nNumber:%s\n\n", X[i].index, X[i].Name, X[i].Sex, X[i].ID, X[i].Number);
fprintf(fp1, "index %d\nName:%s\nSex:%s\nID:%s\nNumber:%s\n\n", X[i].index, X[i].Name, X[i].Sex, X[i].ID, X[i].Number);
fprintf(fp2, "%d\n%s\n%s\n%s\n%s\n", X[i].index, X[i].Name, X[i].Sex, X[i].ID, X[i].Number);
//写下一个成员
i++;
}
//关闭打开的文本
fclose(fp1);
fclose(fp2);
return 0;
}
//如果信息存在,则从副本中读取信息并传递给结构体变量
int get_from_txt()
{
//初始化变量j
int j = 0;
//初始化一个字符串变量用于保存副本中的每行信息
char str[13];
//以读方式打开副本
FILE* fp = fopen("member_temp.txt", "r");
while (j <= 6)
{
//for循环用于给每个成员分配五行信息
for (int i = 1; i <= 5; i++)
{
//第一次执行读取第一行数据,第二次则读取第二行
fgets(str, 13, fp);
//如果读取到换行符,说明已经读取整行信息
if (str[strlen(str) - 1] == '\n')
{
//将换行符改为终止符
str[strlen(str) - 1] = '\0';
//switch case语句分配信息到正确的位置
switch (i)
{
case(1):
{
X[j].index = atoi(str);
break;
};
case(2):
{
strcpy(X[j].Name, str);
break;
};
case(3):
{
strcpy(X[j].Sex, str);
break;
};
case(4):
{
strcpy(X[j].ID, str);
break;
};
case(5):
{
strcpy(X[j].Number, str);
break;
};
};
}
}
//为下一个成员分配信息
j++;
}
//while循环结束则关闭副本
fclose(fp);
return 0;
}
//冒泡排序,用于按成员ID升序排序
int sort_member()
{
//一个用于缓存的结构体变量
member temp;
for (int j = 0; j < 7; j++)
{
for (int k = 1; k < 7 - j; k++)
{
temp = X[k];
//C++标准库strcmp,用于比较字符串,前大于后返回1,相等返回0,后大于前返回-1
if (strcmp(X[k - 1].ID, X[k].ID) == 1)
{
X[k] = X[k - 1];
X[k - 1] = temp;
}
}
}
return 0;
}