大一c语言,羽毛球预约系统问题

这是一个学校羽毛球场的预约系统。该羽毛球场共有8片场地,基本预约单元为一个小时。周二、周四下午3点到9点可预约,周一、三、五下午3点到5点和下午8点到9点可预约(下午5点到8点为教工羽协活动时间不可),周六和周日上午9点到下午9点均可预约。
添加了过了时间就不可预约之前的场地的功能。

问题是:使用该程序时,即使场地空余,也会毫无规律地弹出“输入无效,请重新输入。”提示,预约当天的场地有概率预约成功,但是如果预约明天和后天的空余场地就会一直弹出“输入无效,请重新输入。”

img


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

typedef struct User {
    char number[20];
    char name[20];
    char phone[20];
} User;

typedef struct Reservation {
    char number[20];
    char phone[20];
    char name[20];
    int day;
    int hour;
    int court;
} Reservation;

int weekday() {
    time_t t = time(NULL);
    struct tm tm = *localtime(&t);
    return (tm.tm_wday + 7) % 7;
}

int get_hour() {
    time_t t = time(NULL);
    struct tm tm = *localtime(&t);
    return tm.tm_hour;
}

int valid(int day, int hour) {
    if (day == 1 || day == 3 || day == 5) {
        if (hour >= 15 && hour < 17 || hour >= 20 && hour < 21) {
            return 1;
        }
    } else if (day >= 1 && day <= 5) {
        if (hour >= 15 && hour < 21) {
            return 1;
        }
    } else if (day == 6 || day == 0) {
        if (hour >= 9 && hour < 21) {
            return 1;
        }
    }
    return 0;
}

void generate_court(int courts[][7][8][12]) {
    srand(time(NULL));
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 8; j++) {
            for (int k = 0; k < 12; k++) {
                if (valid((weekday() + i) % 7, k + 9)) {
                    courts[i][(weekday() + i) % 7][j][k] = rand() % 2;
                }
            }
        }
    }
}

int isFileEmpty(const char* filename) {
    FILE *fp = fopen(filename, "r");
    if (fp == NULL) {
        return 1;
    }
    char c = getc(fp);
    fclose(fp);
    return (c == EOF);
}

// 写入文件表头
void writeFileHeader(const char* filename) {
    FILE *fp = fopen(filename, "w");
    if (fp == NULL) {
        printf("无法打开文件 %s\n", filename);
        exit(1);
    }
    fprintf(fp, "学号/工号\t姓名\t手机号\t\t日期\t时间\t场地\n");
    fclose(fp);
}

void save_reservation(Reservation *res) {
    FILE *file;
    if (isFileEmpty("reservations.txt")) {
        writeFileHeader("reservations.txt");
    }
    file = fopen("reservations.txt", "a");
    if (file == NULL)
    {
        printf("无法打开文件\n");
        return;
    }
    fprintf(file, "%s\t%s\t%s\t%d\t%d\t%d\n", res->number, res->name, res->phone,res->day, res->hour, res->court);
    fclose(file);
}

void login(User *user) {
    printf("请输入工号/学号:");
    scanf("%s", user->number);
    printf("请输入姓名:");
    scanf("%s", user->name);
    printf("请输入联系电话:");
    scanf("%s", user->phone);
}


void print_court(int courts[][7][8][12], int day) {
    if (day < 0 || day > 2) {
        printf("输入的日期无效\n");
        return;
    }
    printf("场地信息:\n");
    for (int i = 0; i < 8; i++) {
        printf("场地%d: ", i + 1);
        for (int j = 0; j < 12; j++) {
            if (valid((weekday() + day) % 7, j + 9)) {
                printf("%d时-%d时: %s | ", j + 9, j + 10, courts[day][(weekday() + day) % 7][i][j] ? "已约" : "未约");
            }
        }
        printf("\n");
    }
}

void reserve_court(User *user, int courts[][7][8][12], int day) {
    if (day < 0 || day > 2) {
        printf("输入的日期无效\n");
        return;
    }
    int court, hour;
    print_court(courts, day);

    printf("请输入要预约的场地(1-8):");
    scanf("%d", &court);
    printf("请输入要预约的小时(例如:15-16, 输入15):");
    scanf("%d", &hour);

    if (court >= 1 && court <= 8 && valid((weekday() + day) % 7, hour) && hour > get_hour())
    {
        if (courts[day][(weekday() + day) % 7][court - 1][hour - 9] == 0) {
            courts[day][(weekday() + day) % 7][court - 1][hour - 9] = 1;
            Reservation res;
            strcpy(res.name, user->name);
            strcpy(res.number, user->number);
            strcpy(res.phone, user->phone);
            res.day = day;
            res.hour = hour;
            res.court = court;
            save_reservation(&res);
            printf("预约成功!\n");
        }
        else
        {
            printf("场地已被预约,请重新选择。\n");
        }
    }
    else
    {
        printf("输入无效,请重新输入。\n");
    }
}

void cancel(User *user, int courts[][7][8][12], int day) {
    if (day < 0 || day > 2) {
        printf("输入的日期无效\n");
        return;
    }
    int court, hour;
    printf("请输入要取消预约的场地(1-8):");
    scanf("%d", &court);
    printf("请输入要取消预约的小时(例如:15-16, 输入15):");
    scanf("%d", &hour);

    if (court >= 1 && court <= 8 && valid((weekday() + day) % 7, hour) && hour > get_hour()) {
        if (courts[day][(weekday() + day) % 7][court - 1][hour - 9] == 1) {
            courts[day][(weekday() + day) % 7][court - 1][hour - 9] = 0;
            printf("取消预约成功!\n");
        } else {
            printf("场地未被您预约,无需取消。\n");
        }
    } else {
        printf("场地未被您预约,无需取消。\n");
    }
}

void print_weekday(int day)
{
    struct tm *now;
    time_t current_time;
    time(&current_time);
    now = localtime(&current_time);
    printf("\n");
    switch(day) {
        case 0:
            printf("%04d-%02d-%02d %02d:%02d:%02d",
                now->tm_year + 1900, now->tm_mon + 1, now->tm_mday,
                now->tm_hour, now->tm_min, now->tm_sec);
            break;
        case 1:
            current_time += 86400;
            now = localtime(&current_time);
            printf("%04d-%02d-%02d",
                now->tm_year + 1900, now->tm_mon + 1, now->tm_mday);
            break;
        case 2:
            current_time += 172800;
            now = localtime(&current_time);
            printf("%04d-%02d-%02d",
                now->tm_year + 1900, now->tm_mon + 1, now->tm_mday);
            break;
    }
    switch ((weekday()+day)%7)
    {
        case 0:printf("星期天");break;
        case 1:printf("星期一");break;
        case 2:printf("星期二");break;
        case 3:printf("星期三");break;
        case 4:printf("星期四");break;
        case 5:printf("星期五");break;
        case 6:printf("星期六");break;
    }
}

int main() {
    User user;
    int courts[3][7][8][12];
    generate_court(courts);

    printf("欢迎使用羽毛球场预约系统!\n");
    login(&user);

    int choice, day;
    while (1) {
        printf("\n请选择操作:\n");
        printf("1. 预约场地\n");
        printf("2. 查询信息\n");
        printf("3. 取消预约\n");
        printf("4. 退出\n");
        printf("请输入选项(1-4):");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                printf("请选择预约日期(0:今天,1:明天,2:后天):");
                scanf("%d", &day);
                print_weekday(day);
                reserve_court(&user, courts, day);
                break;
            case 2:
                printf("请选择查询日期(0:今天,1:明天,2:后天):");
                scanf("%d", &day);
                print_weekday(day);
                print_court(courts, day);
                break;
            case 3:
                printf("请选择取消预约的日期(0:今天,1:明天,2:后天):");
                scanf("%d", &day);
                print_weekday(day);
                cancel(&user, courts, day);
                break;
            case 4:
                printf("感谢使用,再见!\n");
                exit(0);
            default:
                printf("输入无效,请重新输入。\n");
                break;
        }
    }

    return 0;
}

你看了我推荐给你的那个代码么?你用那个试试看,是可以运行的。

认真查看后发现,程序中并没有对日期进行正确的判断。由于使用“% 7”运算符,代码假定今天是星期0,即星期日,但这是不正确的。可以尝试在“valid”函数中打印“day”和“weekday()”的值来看看是否符合预期。
下面是修改后的代码,增加了正确的日期计算和错误提示信息:

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

typedef struct User {
    char number[20];
    char name[20];
    char phone[20];
} User;

typedef struct Reservation {
    char number[20];
    char phone[20];
    char name[20];
    int day;
    int hour;
    int court;
} Reservation;

int weekday() {
    time_t t = time(NULL);
    struct tm tm = *localtime(&t);
    return tm.tm_wday;
}

int get_hour() {
    time_t t = time(NULL);
    struct tm tm = *localtime(&t);
    return tm.tm_hour;
}

int valid(int day, int hour) {
    if (day == 0 || day == 2 || day == 4) {
        if (hour >= 15 && hour < 17 || hour >= 20 && hour < 21) {
            return 1;
        }
    } else if (day >= 1 && day <= 5) {
        if (hour >= 15 && hour < 21) {
            return 1;
        }
    } else if (day == 6 || day == 7) {
        if (hour >= 9 && hour < 21) {
            return 1;
        }
    }
    return 0;
}

void generate_court(int courts[][7][8][12]) {
    srand(time(NULL));
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 7; j++) {
            for (int k = 0; k < 8; k++) {
                for (int l = 0; l < 12; l++) {
                    if (valid((weekday() + i) % 7, l + 9)) {
                        courts[i][(weekday() + i) % 7][k][l] = rand() % 2;
                    }
                }
            }
        }
    }
}

int isFileEmpty(const char* filename) {
    FILE *fp = fopen(filename, "r");
    if (fp == NULL) {
        return 1;
    }
    char c = getc(fp);
    fclose(fp);
    return (c == EOF);
}

void writeFileHeader(const char* filename) {
    FILE *fp = fopen(filename, "w");
    if (fp == NULL) {
        printf("无法打开文件 %s\n", filename);
        exit(1);
    }
    fprintf(fp, "学号/工号\t姓名\t手机号\t\t日期\t时间\t场地\n");
    fclose(fp);
}

void save_reservation(Reservation *res) {
    FILE *file;
    if (isFileEmpty("reservations.txt")) {
        writeFileHeader("reservations.txt");
    }
    file = fopen("reservations.txt", "a");
    if (file == NULL)
    {
        printf("无法打开文件\n");
        return;
    }
    fprintf(file, "%s\t%s\t%s\t%d\t%d\t%d\n", res->number, res->name, res->phone,res->day, res->hour, res->court);
    fclose(file);
}

void login(User *user) {
    printf("请输入工号/学号:");
    scanf("%s", user->number);
    printf("请输入姓名:");
    scanf("%s", user->name);
    printf("请输入联系电话:");
    scanf("%s", user->phone);
}

void print_court(int courts[][7][8][12], int day) {
    if (day < 0 || day > 2) {
        printf("输入的日期无效\n");
        return;
    }
    printf("场地信息:\n");
    for (int i = 0; i < 8; i++) {
        printf("场地%d: ", i + 1);
        for (int j = 0; j < 12; j++) {
            if (valid((weekday() + day) % 7, j +9)) {
                printf("%d时-%d时: %s | ", j + 9, j + 10, courts[day][(weekday() + day) % 7][i][j] ? "已约" : "未约");
            }
        }
        printf("\n");
    }
}

void reserve_court(User *user, int courts[][7][8][12], int day) {
    if (day < 0 || day > 2) {
        printf("输入的日期无效\n");
        return;
    }
    if (day < 0) {
        printf("输入的日期无效,请输入0-2之间的数字。\n");
        return;
    }
    int court, hour;
    print_court(courts, day);

    printf("请输入要预约的场地(1-8):");
    if (scanf("%d", &court) != 1 || court < 1 || court > 8) {
        printf("输入无效,请输入1-8之间的数字。\n");
        return;
    }
    printf("请输入要预约的时间(例如:15-16, 输入15):");
    if (scanf("%d", &hour) != 1 || !valid((weekday() + day) % 7, hour) || hour <= get_hour()) {
        printf("输入无效,请按照正确格式输入有效的预约时间。\n");
        return;
    }

    if (courts[day][(weekday() + day) % 7][court - 1][hour - 9] == 0) {
        courts[day][(weekday() + day) % 7][court - 1][hour - 9] = 1;
        Reservation res;
        strcpy(res.name, user->name);
        strcpy(res.number, user->number);
        strcpy(res.phone, user->phone);
        res.day = day;
        res.hour = hour;
        res.court = court;
        save_reservation(&res);
        printf("预约成功!\n");
    } else {
        printf("场地已被预约,请重新选择。\n");
    }
}

void cancel(User *user, int courts[][7][8][12], int day) {
    if (day < 0 || day > 2)
{
        printf("输入的日期无效\n");
        return;
    }
    if (day < 0) {
        printf("输入的日期无效,请输入0-2之间的数字。\n");
        return;
    }
    int court, hour;
    printf("请输入要取消预约的场地(1-8):");
    if (scanf("%d", &court) != 1 || court < 1 || court > 8) {
        printf("输入无效,请输入1-8之间的数字。\n");
        return;
    }
    printf("请输入要取消预约的时间(例如:15-16, 输入15):");
    if (scanf("%d", &hour) != 1 || !valid((weekday() + day) % 7, hour) || hour <= get_hour()) {
        printf("输入无效,请按照正确格式输入有效的取消预约时间。\n");
        return;
    }

    if (courts[day][(weekday() + day) % 7][court - 1][hour - 9] == 1) {
        courts[day][(weekday() + day) % 7][court - 1][hour - 9] = 0;
        printf("取消预约成功!\n");
    } else {
        printf("场地未被您预约,无需取消。\n");
    }
}

void print_weekday(int day) {
    struct tm *now;
    time_t current_time;
    time(&current_time);
    now = localtime(&current_time);
    printf("\n");
    switch(day) {
        case 0:
            printf("%04d-%02d-%02d %02d:%02d:%02d",
                now->tm_year + 1900, now->tm_mon + 1, now->tm_mday,
                now->tm_hour, now->tm_min, now->tm_sec);
            break;
        case 1:
            current_time += 86400;
            now = localtime(&current_time);
            printf("%04d-%02d-%02d",
                now->tm_year + 1900, now->tm_mon + 1, now->tm_mday);
            break;
        case 2:
            current_time += 172800;
            now = localtime(&current_time);
            printf("%04d-%02d-%02d",
                now->tm_year + 1900, now->tm_mon + 1, now->tm_mday);
            break;
        default:
            printf("输入无效,请输入0-2之间的数字。\n");
            break;
    }
    switch ((weekday()+day)%7) {
        case 0:printf("星期天");break;
        case 1:printf("星期一");break;
        case 2:printf("星期二");break;
        case 3:printf("星期三");break;
        case 4:printf("星期四");break;
        case 5:printf("星期五");break;
        case 6:printf("星期六");break;
    }
}

int main() {
    User user;
    int courts[3][7][8][12];
    generate_court(courts);

    printf("欢迎使用羽毛球场预约系统!\n");
    login(&user);

    int choice, day;
    while (1) {
        printf("\n请选择操作:\n");
        printf("1. 预约场地\n");
        printf("2. 查询信息\n");
        printf("3. 取消预约\n");
        printf("4. 退出\n");
        printf("请输入选项(1-4):");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                printf("请选择预约日期(0:今天,1:明天,2:后天):");
                scanf("%d", &day);
                print_weekday(day);
                reserve_court(&user, courts, day);
                break;
            case 2:
                printf("请选择查询日期(0:今天,1:明天,2:后天):");
                scanf("%d", &day);
                print_weekday(day);
                print_court(courts, day);
                break;
            case 3:
                printf("请选择取消预约的日期(0:今天,1:明天,2:后天):");
                scanf("%d", &day);
                print_weekday(day);
                cancel(&user, courts, day);
                break;
            case 4:
                printf("感谢使用,再见!\n");
                exit(0);
            default:
                printf("输入无效,请重新输入。\n");
                break;
        }
    }

    return 0;
}