如何用结构体和文件实现机房上机模拟系统

根据用户输入的账号和密码,判断用户是否合法,如果是合法用户则记录用户的账号、上机实践,如果为非法用户则提示账号或密码错误,请重试。用户上机结束后,记录用户的下机时间并计算费用(设每小时时间费用为1元)。
用两个文件存放
定义两个结构体。

下面是一个C语言的示例程序,可以实现用户登录验证和记录用户上机和下机时间,并计算上机时间和费用,并将记录写入两个文件中。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_USER 100 // 最大用户数
#define MAX_NAME 20 // 用户名最大长度
#define MAX_PASS 20 // 密码最大长度

// 用户结构体
typedef struct {
    char name[MAX_NAME];
    char pass[MAX_PASS];
    time_t start_time; // 上机时间
    time_t end_time; // 下机时间
} User;

// 用户管理结构体
typedef struct {
    User users[MAX_USER];
    int count; // 当前用户数
} UserManager;

// 初始化用户管理器
void init_user_manager(UserManager *manager) {
    manager->count = 0;
}

// 添加用户
void add_user(UserManager *manager, const char *name, const char *pass) {
    if (manager->count >= MAX_USER) {
        printf("Error: Too many users.\n");
        return;
    }
    User *user = &manager->users[manager->count];
    strcpy(user->name, name);
    strcpy(user->pass, pass);
    user->start_time = 0;
    user->end_time = 0;
    manager->count++;
}

// 查找用户
User *find_user(UserManager *manager, const char *name) {
    for (int i = 0; i < manager->count; i++) {
        if (strcmp(manager->users[i].name, name) == 0) {
            return &manager->users[i];
        }
    }
    return NULL;
}

// 记录用户上机时间
void logon_user(UserManager *manager, const char *name) {
    User *user = find_user(manager, name);
    if (user == NULL) {
        printf("Error: Invalid user.\n");
        return;
    }
    if (user->start_time != 0) {
        printf("Error: User already logged on.\n");
        return;
    }
    user->start_time = time(NULL);
    printf("User '%s' logged on at %s", user->name, ctime(&user->start_time));
}

// 记录用户下机时间,并计算费用
void logoff_user(UserManager *manager, const char *name) {
    User *user = find_user(manager, name);
    if (user == NULL) {
        printf("Error: Invalid user.\n");
        return;
    }
    if (user->start_time == 0) {
        printf("Error: User has not logged on.\n");
        return;
    }
    user->end_time = time(NULL);
    double duration = difftime(user->end_time, user->start_time);
    double cost = duration / 3600;
    printf("User '%s' logged off at %s", user->name, ctime(&user->end_time));
    printf("User '%s' used the computer for %.1f hours, and the cost is %.1f yuan.\n", user->name, duration / 3600, cost);
    // 将记录写入文件
    FILE *log_file = fopen("log.txt", "a");
    fprintf(log_file, "User '%s' logged on at %s", user->name, ctime(&user->start_time));
    fprintf(log_file, "User '%s' logged off at %s", user->name, ctime(&user->end_time));
        fprintf(log_file, "User '%s' used the computer for %.1f hours, and the cost is %.1f yuan.\n\n", user->name, duration / 3600, cost);
    fclose(log_file);
    // 重置用户状态
    user->start_time = 0;
    user->end_time = 0;
}

int main() {
    UserManager manager;
    init_user_manager(&manager);

    // 从文件中读取用户信息
    FILE *user_file = fopen("user.txt", "r");
    char name[MAX_NAME];
    char pass[MAX_PASS];
    while (fscanf(user_file, "%s %s", name, pass) != EOF) {
        add_user(&manager, name, pass);
    }
    fclose(user_file);

    // 进入命令行交互模式
    while (1) {
        printf("Please enter username and password, separated by a space (q to quit): ");
        char name[MAX_NAME];
        char pass[MAX_PASS];
        scanf("%s", name);
        if (strcmp(name, "q") == 0) {
            break;
        }
        scanf("%s", pass);
        User *user = find_user(&manager, name);
        if (user == NULL || strcmp(user->pass, pass) != 0) {
            printf("Invalid username or password. Please try again.\n");
        } else {
            logon_user(&manager, name);
            printf("Welcome, %s!\n", name);
            while (1) {
                printf("Enter 'logoff' to log off (q to quit): ");
                char command[10];
                scanf("%s", command);
                if (strcmp(command, "logoff") == 0) {
                    logoff_user(&manager, name);
                    break;
                } else if (strcmp(command, "q") == 0) {
                    logoff_user(&manager, name);
                    break;
                } else {
                    printf("Invalid command. Please try again.\n");
                }
            }
        }
    }

    return 0;
}

这段代码中,首先在logoff_user函数中打开一个名为log.txt的文件,并将用户上机和下机的时间、使用时间和费用写入文件中。然后关闭文件,并在函数末尾将用户状态重置。

然后在main函数中,首先从user.txt文件中读取用户信息,然后进入命令行交互模式,接收用户输入的用户名和密码,进行验证。如果验证通过,则调用logon_user函数记录用户上机时间,并进入循环等待用户输入下机指令。如果用户输入了logoff指令,则调用logoff_user函数记录用户下机时间,并退出循环。如果用户输入了q指令,则调用logoff_user函数记录用户下机时间,并退出循环,程序结束。如果用户输入了其他指令,则提示用户指令无效,并等待用户继续输入。

下面是一个简单的C语言程序,使用结构体和文件实现机房上机模拟系统:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_USERS 100
#define MAX_NAME_LEN 20
#define MAX_PASSWORD_LEN 20

// 定义用户结构体
typedef struct {
    char name[MAX_NAME_LEN];
    char password[MAX_PASSWORD_LEN];
    int is_valid; // 是否合法用户的标志
} User;

// 定义上机记录结构体
typedef struct {
    char name[MAX_NAME_LEN];
    time_t login_time;
    time_t logout_time;
} Record;

// 全局变量
User users[MAX_USERS];
int num_users = 0;
Record records[MAX_USERS];
int num_records = 0;

// 函数声明
void load_users(char *filename);
void save_users(char *filename);
void load_records(char *filename);
void save_records(char *filename);
int login();
void logout(int index);
void print_records();

int main() {
    load_users("users.txt");
    load_records("records.txt");
    while (1) {
        int choice;
        printf("1. 登录\n2. 退出\n");
        printf("请输入选项:");
        scanf("%d", &choice);
        if (choice == 1) {
            int index = login();
            if (index >= 0) {
                printf("登录成功!\n");
                printf("1. 上机\n2. 下机\n");
                printf("请输入选项:");
                scanf("%d", &choice);
                if (choice == 1) {
                    time_t now = time(NULL);
                    records[num_records].login_time = now;
                    strcpy(records[num_records].name, users[index].name);
                    num_records++;
                    printf("上机成功!\n");
                } else if (choice == 2) {
                    logout(index);
                }
            } else {
                printf("账号或密码错误,请重试!\n");
            }
        } else if (choice == 2) {
            break;
        }
    }
    save_users("users.txt");
    save_records("records.txt");
    print_records();
    return 0;
}

// 加载用户信息
void load_users(char *filename) {
    FILE *fp = fopen(filename, "r");
    if (fp) {
        while (fscanf(fp, "%s %s %d", users[num_users].name, users[num_users].password, &users[num_users].is_valid) == 3) {
            num_users++;
        }
        fclose(fp);
    }
}

// 保存用户信息
void save_users(char *filename) {
    FILE *fp = fopen(filename, "w");
    if (fp) {
        for (int i = 0; i < num_users; i++) {
            fprintf(fp, "%s %s %d\n", users[i].name, users[i].password, users[i].is_valid);
        }
        fclose(fp);
    }
}

// 加载上机记录
void load_records(char *filename) {
    FILE *fp = fopen(filename, "r");
    if (fp) {
        while (fscanf(fp, "%s %ld %ld", records[num_records].name, &records[num_records].login_time, &records[num_records].logout_time) == 3) {
            num_records++;
        }
        fclose(fp);
    }
}

// 保存上机记录
void save_records(char *filename) {
    FILE *fp = fopen(filename, "w");
    if(fp) {
        for (int i = 0; i < num_records; i++) {
            fprintf(fp, "%s %ld %ld\n", records[i].name, records[i].login_time, records[i].logout_time);
        }
        fclose(fp);
    }
}

// 登录
int login() {
    char name[MAX_NAME_LEN];
    char password[MAX_PASSWORD_LEN];
    printf("请输入用户名:");
    scanf("%s", name);
    printf("请输入密码:");
    scanf("%s", password);
    for (int i = 0; i < num_users; i++) {
        if (strcmp(users[i].name, name) == 0 && strcmp(users[i].password, password) == 0 && users[i].is_valid) {
            return i;
        }
    }
    return -1;
}

// 下机
void logout(int index) {
    time_t now = time(NULL);
    for (int i = num_records - 1; i >= 0; i--) {
        if (strcmp(records[i].name, users[index].name) == 0 && records[i].logout_time == 0) {
            records[i].logout_time = now;
            printf("下机成功!\n");
            printf("本次上机时间为:%ld 秒\n", (long)(records[i].logout_time - records[i].login_time));
            int cost = (int)((records[i].logout_time - records[i].login_time) / 3600);
            printf("本次费用为:%d 元\n", cost);
            return;
        }
    }
    printf("您还没有上机,请先上机!\n");
}

// 打印上机记录
void print_records() {
    printf("上机记录:\n");
    for (int i = 0; i < num_records; i++) {
        printf("%s 上机时间:%s 下机时间:%s\n", records[i].name, ctime(&records[i].login_time), ctime(&records[i].logout_time));
    }
}

上面的代码定义了两个结构体,User 和 Record,分别用于存放用户信息和上机记录。load_users、save_users、load_records、save_records 四个函数用于加载和保存用户信息和上机记录,这里使用了文件操作来读写文件。

login 函数用于登录,根据用户输入的账号和密码,遍历用户数组,如果找到合法的用户则返回该用户的索引,否则返回 -1。

logout 函数用于下机,根据用户的索引遍历上机记录数组,找到最近的一条记录并将其下机时间设置为当前时间,计算费用并输出。

print_records 函数用于打印所有的上机记录。

在主函数中,使用一个循环来不断接受用户输入的选项,如果用户选择登录,则调用 login 函数进行登录,如果登录成功则再次接受用户输入的选项,如果是上机,则记录上机时间,如果是下机,则调用 logout 函数进行下机操作。如果用户选择退出,则跳出循环。

最后,在程序结束前,调用 save_users 和 save_records 函数将用户信息和上机记录保存到文件中,并调用 print_records 函数打