项目要求:
使用C语言,制作一个在命令行运行的点名程序,该程序运行时可指定班级的花名册文件,运行后在界面上显示随机抽取名字的过程,速度由快到慢,逐渐定格到某一个“幸运儿”上,程序结束。
- 指定普通文本文件(*.txt)为名单,以行为单位读取学员名字。
- 随机抽取的过程在终端动态展现出来,如图所示
项目代码展示:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
int main(int argc, char **argv)
{
// 按只读方式打开制定的名单
FILE *fp = fopen("/mnt/hgfs/share/wen/text.txt", "r");
if(fp == NULL)
{
perror("打开文件失败");
exit(0);
}
// 假设起始名字不超过100个,每个名字不超过20个字符
char (*names)[20] = calloc(100, 20);
int numbers = 0; // 总人数
// 将名单内容按行读取,并去除换行符'\n'
bool done = false;
for(int i=0; i<100; i++)
{
if(fgets(names[i], 20, fp) == NULL)
{
done = true;
break;
}
names[i][strlen(names[i])-1] = '\0';
numbers++;
}
// 名字超过100个,存储空间不够
if(!done)
{
// 扩容到200个名单
names = realloc(names, 200*20);
for(int i=100; i<200; i++)
{
if(fgets(names[i], 20, fp) == NULL)
{
done = true;
break;
}
names[i][strlen(names[i])-1] = '\0';
numbers++;
}
}
// 名字超过200个,存储空间不够,放弃继续读取
if(!done)
{
printf("抱歉,班级人数最多支持200人,本次只取前200名\n");
}
// 开始随机点名
srand(time(NULL));
int lastRandValue=-1;
for(int i=0; i<35; i++)
{
// 清空原有数据
fprintf(stderr, "\r");
for(int k=0;k<20;k++)
fprintf(stderr, " ");
// 获取一个与上次不一样的随机值
int newRandValue = rand()%numbers;
while(newRandValue == lastRandValue)
newRandValue = rand()%numbers;
lastRandValue = newRandValue;
// 快速闪过前20个随机姓名
if(i<20)
{
fprintf(stderr, "\r%s", names[newRandValue]);
usleep(100*1000);
}
// 中速闪过10个随机姓名
else if(i<30)
{
fprintf(stderr, "\r%s", names[newRandValue]);
usleep(200*1000);
}
// 慢速闪过3个随机姓名
else if(i<35)
{
fprintf(stderr, "\r%s", names[newRandValue]);
usleep(400*1000);
}
}
printf("\n");
return 0;
}
效果展示
注意事项
要确保程序读取的路径下有需要读取的文件如图中我的路径是
/mnt/hgfs/share/wen/text.txt
如果是window下的话可以根据我的电脑下上面显示路径填写如图
根据自己的实际情况填写