基于C命令行的随机点名器
项目描述
使用C语言,制作一个在命令行运行的点名程序,该程序运行时可指定班级的花名册文件,运行后在界面上显示随机抽取名字的过程,速度由快到慢,逐渐定格到某一个“幸运儿”上,程序结束。
功能要求
- 指定普通文本文件(*.txt)为名单,以行为单位读取学生名字.
- 随机抽取的过程在终端动态展示出来,速度呈慢-快-慢渐变效果.
- 从名单中抽取名字后,将名单中相应的名字去掉.
- 可以一次抽取若干位同学.
- 抽取到最后,当名单上的同学不足以抽取一次时,应当可以选择还原名单(覆盖).
思路:
-
由于需要将读取的名字从文件中删去,如果直接在文件上操作会比较麻烦;所以我定义一个二维数组,将文件中的名字全部读取到数组中,在数组中进行相关操作,最后在将数组写回到文件中.
/*定义一个Get_txt()函数从文件中读取数据,该函数的输入参数为二维数组及读取文件的路径+名称 返回值为读取文件的个数*/ int Get_txt(char ch[][SIZE_NAME],char* txt); /*由于在Windows系统中,文本文件默认以`\r\n`作为换行(这一点在上一个笔记有验证过);而我们在展示名字时并不需要换行,所以定义一个Deal_line()函数来处理二维数组中的\r\n*/ void Deal_line(char ch[][SIZE_NAME],int count); //定义Del_name()函数来删除抽取的学生的名字 void Del_name(char ch[][SIZE_NAME],int mem[],int* count,int number); /*定义一个Write_file()函数将二维数组的内容重写回到文件中*/ void Write_file(char ch[][SIZE_NAME],char* txt,int count);
-
随机抽取学生名字这个功能通过使用随机数来实现.
/*定义Pitch_on()函数从数组中随机抽取若干名学生,抽取过程的速度呈现慢-快-慢渐变效果*/ void Pitch_on(char ch[][SIZE_NAME],int mem[],int count,int number) { ... for(i = 0;i < TIME_PITCH;i++) { //system("cls");//清屏(使用该函数得到的视觉效果更好) for(j = 0;j < number;j++) { flat1 = 1; mem[j] = 0; //由于延时函数没有放在这个循环里面,如果直接使用rand()来产生随机数, //存在连续几次都是同一个随机数情况. srand(time(NULL)+i+j); num = (rand()) % count; //对产生相同的随机数处理 for(n = 0;n < j;n++) { if(num == mem[n]) { j --; flat1 = 0; } } if(flat1 == 1) { mem[j] = num; printf("%s\t",ch[num]); } } ... }
-
由于抽取若干名字时,可能存在名单的名字数量小于抽取人数的情况,这是需要询问是否重新覆盖名单;那就必须要有一份没抽过名字的名单才可以进行覆盖.
//定义Set_backup_name()通过文件名来设置备份文件名 void Set_backup_name(char* txt,char* backup); //定义BackUp()来设置备份文件 void BackUp(char ch[][SIZE_NAME],char* backup,int count); //定义Over_txt()来覆盖文件,即将备份文件的内容覆盖到文件中.
4.主函数部分
int main(int argc,char** argv)
{
int i = 0;
int j = 0;
int num = 0;
int number = 1;//表示一次性抽多少名同学
int mem[PITCH_NUMBER] = {0};//存储一次性抽取多个同学的编号
char ch[COUNT_NAME][SIZE_NAME] = {0};//存储名单中的成员
char *txt = argv[1];//存储名单的地址+名称
char *backup = calloc(1,strlen(txt)+2);//存储备份文件名
//判断是抽取一位同学还是多位同学,最多输入9
if(argv[2] != NULL)
number = (int)(argv[2][0]-'0');
int count = Get_txt(ch,txt);
Deal_line(ch,count);
Set_backup_name(txt,backup);
BackUp(ch,backup,count);
//剩余学生小于抽取个数
if(count < number)
{
Over_txt(ch,mem,txt,backup,count);
return 0;
}
Pitch_on(ch,mem,count,number);
Del_name(ch,mem,&count,number);
//显示名单中剩余人数
printf("\nnumber:%d\n",count);
Write_file(ch,txt,count);
//释放堆空间
free(backup);
backup = NULL;
return 0;
}
结果展示:
这是我第一个C小项目,思维逻辑可能还不是很标准,不喜勿喷。