C语言小项目—随机点名器(含文件IO)

文章介绍了使用C语言编写的一个程序,通过读取txt文件中的学生信息,实现随机抽取学生姓名的功能,并处理文件的打开、读取、写入和关闭操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

话不多说直接上代码,部分功能未增添,等待ing。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h> 
#include <sys/time.h>  

//通过加权实现平均的抽取,保证人人都会被抽到(未实现)
/* 
    结构体在加一个权,
    平均权等于程序运行次数/总人数,
    当一个人的权大于等于平均权,就不抽他。
    有没有更好的方法呢?
 */
#define INITIAL_SIZE   100 //数组初始大小
#define INCR_SIZE  50      //数组每次增加大小 
/* 
    1.文件读取,存入结构体,写入
    2.随机数生成
    3.点名函数
    4.菜单函数
 */
struct Student_Info
{
    int id;//编号
    char name[20];//姓名
    int num;
};
typedef struct Student_Info Student;//结构体设置别名

//全局变量区
FILE *fp;//创建文件类型指针变量
long studentSize  = 0;//当前学生数量
Student* records; //记录学生信息的数组
//char savetag; //信息是否保存的标志 0 保存  1 未保存 
long number;//程序被运行的次数

void selection();//随机抽取
long random_num();
void readFile(FILE * fp, struct Student_Info *records);//读取文件并存入结构体
FILE * openFile(char * str);//打开文件
void writeFile(FILE *fp , char * str);//写文件
void closeFile();//关闭文件



int main()
{

    fp = openFile("name.txt");
    // 动态分配学生数组  
    records = (Student*)malloc(INITIAL_SIZE * sizeof(Student));  
    if (records == NULL) {  
        printf("内存分配失败\n");  
        return 1;  
    }
    //读取文件,初始化数据  
    readFile(fp,records);
    //打印现在读取到学生结构体列表
    for (int i = 0; i < studentSize; i++)
    {
        printf("第%d个学生的id是: %d, 姓名是:%s\n",i+1,(*(records + i)).id,(*(records + i)).name);
    }
    
    //writeFile(fp,"雷电将军\n");//每次新增后,结构体数据也要新增  
    //随机抽取
    selection();

    //查找学生存在?好像没必要写
    closeFile(fp);
}
//随机抽取
void selection()
{
    printf("开始随机抽取!\n");
    for(int i = 0; i < studentSize; i++)
    {     
        system("clear");
        printf("%s\n",(*(records+random_num())).name);
        //sleep(1); 
        // 暂停0.05秒  
        usleep(50000); 
    }
}
struct timeval tv; 
//返回一个随机0~studentSize的数
long random_num()
{ 
    gettimeofday(&tv, NULL);  
    long long milliseconds = tv.tv_sec*1000LL + tv.tv_usec/1000;
    // 设置随机数种子  
    //srand(time(NULL));  
    srand(milliseconds);  
  
    // 生成1个随机数并返回    
    return  rand()%studentSize;//随机返回0-studentSize的数 
}

//读取文件
void readFile(FILE * fp, struct Student_Info *records)
{    
    if(fp == NULL)
       {
        printf("你读取文件失败,程序结束");
        exit(0);
       } 
    char string[20];//定义一次读取的字符长度
    printf("开始读取文件内容!\n");
    rewind(fp);//将指针移动到文件头
    while (fgets(string,20,fp) != NULL)     
    {       
        //将读取的一个名字存入数组
        int i = 0;  
        while (string[i] != '\n') {  
            //printf("%c", string[i]);  
            i++;  
        }
        //将此次读取的名字转换成结构体对象
        (*(records+studentSize)).id = studentSize;//存储编号
        for (int j = 0; j < i; j++)
        {
            (*(records+studentSize)).name[j] = string[j];//存储名字
        }
        (*(records+studentSize)).name[i] ='\0';
        studentSize++;//每记录一个学生,数量加1
        //printf("\n");  
    }
    //printf("\n");
}

//以读写的方式打开文件
FILE * openFile(char * str)
{

    if((fp = fopen(str,"rb+")) == NULL)
    {
        printf("文件打开失败,请检查文件的文件名或文件路径!");
        exit(0);
    }
    printf("文件打开成功!");
    return fp;
}

//写文件
void writeFile(FILE *fp , char * str)
{
    if(fp == NULL)
       {
        printf("你写的文件不存在,程序结束\n");
        exit(0);
       } 
    // 将文件指针移动到文件末尾    
    if (fseek(fp, 0, SEEK_END) != 0) {  
        fprintf(stderr, "在文件末尾定位时出错\n");  
        exit(EXIT_FAILURE);  
    }  
    // 将得到的字符串写入文件末尾  
    if (fputs(str, fp) == EOF) {  
        fprintf(stderr, "写入文件时出错\n");  
        exit(EXIT_FAILURE);  
    }  
  
    printf("写入成功!\n"); 

}
//关闭文件
void closeFile()
{
    fclose(fp) ? printf("文件关闭失败\n") : printf("文件关闭成功\n");
}


txt格式要求:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值