Student Information Management System

Student Information Management System

All the mark points are marked in the table, if you cannot find the evaluation point in the webpage, this table will help you.

evaluation pointlink1link2link3Note
Basic function – addviewlogicdata access
Basic function – displayviewdata access
Basic function – searchviewdata access
Basic function – sortviewdata access
Basic function – save to file(log)data access
Basic function – read from file(log)viewdata access
Extended function – delete studentviewlogicdata access
Extended function – modify studentviewlogicdata access
Extended function – OOintroduction
Extended function – databaseintroductiondetailed design
Extended function – version controlintroduction
Extended function – logintroductiondata access

The Basic function “sort” contians extended like sort by studentId, name, age, etc.
The extended function “log” appear too many times so I did not give the links here.

1.Introduction

This is a system for managing the students’ information (SIMS in short). The system contains three hierachical layers which are view, logic and data access.
At the very top layer-- view layer contains all human-computer interactions. All the client operations will be finished here.
The 2nd layer is the logic layer. It contains all logic operations including search for a student, sort the student grades, etc.
The 3rd layer is to communicate with database. It will automatically control the database with the order from logic layer.

LayerFunctionNote
ViewAll human-computer interactions.No logic nor data control at all
LogicHandle the orders from the view layer, all the memory operations will be executed here, but data operations will be sent to the 3rd layerThis is the core layer of the system
DataHandle all the data operations from logic layerConnection between memory and database

2.Outline design

2.1 Functions of system

This system is similar to a DBMS, it contains add, delete, modify and query for a database. The detailed functions design is shown in the graph below.
请添加图片描述

2.2 UML sequence diagram

Client View Logic Data request request(Add, display, sort, search) Handle the request get data Handle the SQL return data Logic processing return the result Display Client View Logic Data

3.Extended

3.1 Object-Oriented design

To manage the students system, in memory operations of students, I used the object-oriented design for convenience. But due to C language does not have “class”, so I used struct and function to implement the class.

This is the class diagram of the system:

3.2 Database(MySQL)

To store the information in disk, we need a database to store all the information. I chose to use MySQL database.

This is the only table my database design:

3.3 Version control(Git)

Version control is important to keep track of changes — and keep every team member working off the latest version. I should use version control software for all code, files, and assets that multiple team members will collaborate on.

I use github server to store and do the version control.
This is the commit history of the project:

See my project on:
https://github.com/FTDfangge/StudentInfoManager

3.4 log file

The reason log files exist is that software and hardware developers find it easier to troubleshoot and debug their creations when they access a textual record of the events that the system is producing.

I use log file to record every operation that did by the client.

This is the log file until I wrote:

4. Detialed design

4.1 View

I loop the menu until user input exit, here is the core code.

void UImenu(){
    struct StudentList* studentList = (struct StudentList*) malloc(sizeof (struct StudentList));
    studentList->pre = NULL;
    studentList->next = NULL;
    initializeFromDatabase(&studentList);
    while(true){
        printf("\n=====Student Information management System=====\n");
        printf("=====Menu=====\n");
        printf("1. Display all students\n");
        printf("2. Sort the display\n");
        printf("3. Add student\n");
        printf("4. Modify student\n");
        printf("5. Delete student\n");
        printf("6. Search\n");
        printf("7. Check log file\n");
        printf("8. exit\n");
        printf("Plz input the choice(1~7): ");
        int choice=0;
        scanf("%d",&choice);
        switch (choice) {
            case 1:{
                UIdisplay();
                break;
            }
            case 2:{
                UIsort(&studentList);
                break;
            }
            case 3:{
                UIaddStu(&studentList);
                break;
            }
            case 4:{
                UImodify(&studentList);
                break;
            }
            case 5:{
                UIdeleteStu(&studentList);
                break;
            }
            case 6:{
                UIsearch(&studentList);
                break;
            }
            case 7:{
                UIlog();
                break;
            }
            case 8:{
                exit(0);
            }
            default:{
                break;
            }
        }
    }
}

4.1.1 display all students’ info

I directly called the data access layer to get the data from database.
Here is the core code.

void UIdisplay(){
    //Directly call the data access layer
    printDatabase(); //call the data access layer
}

The called function is in 4.3.4.

4.1.2 add a new student

Let user input the information of new student, and call the logic layer to finish.

void UIaddStu(struct StudentList** list){
    printf("\n=====Add a student=====\n");

    struct Student* student = (struct Student*) malloc(sizeof (struct Student));
    printf("Plz input the student info:\n"
           "studentId: ");
    scanf("%d",&(*student).stuId);
    printf("\nstudent name: ");
    scanf("%s",(*student).name);
    printf("\nstudent gender: ");
    scanf("%s",(*student).gender);
    printf("\nstudent age: ");
    scanf("%d", &(*student).age);
    printf("\nstudent C score: ");
    scanf("%d", &(*student).CScore);
    printf("\nstudent English score: ");
    scanf("%d", &(*student).EngScore);
    printf("\nAdding...\n");

    add(student, list); //call the logic layer
    
}

the called logic layer is here: logic

4.1.3 sort

Each attribute contained in the student could be the sorted option.
And sort is so easy that it will not pass the logic layer.

void UIsort(struct StudentList** list){
    printf("\n1. Student id\n2. name\n3. gender\n4. age\n5. C score\n6. English Score\n");
    printf("\nPlz select the attribute to sort: ");
    int choice = 0;
    scanf("%d", &choice);
    switch (choice) {
        case 1:{
            sortById();//call the data access layer
            break;
        }
        case 2:{
            sortByName();//call the data access layer
            break;
        }
        case 3:{
            sortByGender();//call the data access layer
            break;
        }
        case 4:{
            sortByAge();//call the data access layer
            break;
        }
        case 5:{
            sortByCScore();//call the data access layer
            break;
        }
        case 6:{
            sortByEngScore();//call the data access layer
            break;
        }
        default:
            break;
    }
}

The called data access layer design is here

4.1.4 search

It could be searched by each attribute of student.

void UIsearch(struct StudentList** list){
    char **choices = malloc(sizeof(char*) * 6);
    choices[0] = "stuId";
    choices[1] = "name";
    choices[2] = "gender";
    choices[3] = "age";
    choices[4] = "CScore";
    choices[5] = "EngScore";

    printf("\n1. Student id\n2. name\n3. gender\n4. age\n5. C score\n6. English Score\n");
    printf("\nPlz select the attribute to search: ");
    int choice = 0;
    fflush(stdin);
    scanf("%d", &choice);
    choice--;
    printf("\n Plz input the value of %s: ",choices[choice]);
    char value[255];
    fflush(stdin);
    scanf("%s", value);
    search(choices[choice], value);
}

4.1.5 modify
void UImodify(struct StudentList** list){
    printf("\nPlz input the student id to be modify: ");
    int stuId;
    scanf("%d",&stuId);
    modifyStudentInList(stuId, list);
}

4.1.6 delete
void UIdeleteStu(struct StudentList** list){
    printf("\nPlz input the student number to delete: ");
    int stuId;
    scanf("%d",&stuId);
    delete(stuId, list);
}

4.1.7 read log from file
void UIlog(){
    logPrint();
}

4.2 Logic

4.2.1 add a student

It will firstly check if the student exist, then add it to the linked list(in memory), and it will sync with database(in disk).

void add(struct Student* student, struct StudentList** list){
    //judge if the student exist in the list.
    struct StudentList* listPtr = *list;
    while (listPtr){
        if(listPtr->data.stuId == (*student).stuId){
            printf("\nERROR: The student is already existed, add failed.\n");
            return;
        }
        listPtr = listPtr->next;
    }

    //Add to the list
    struct StudentList* newnode = (struct StudentList*) malloc(sizeof (struct StudentList));
    newnode->data = *student;
    newnode->pre = NULL;
    newnode->next = *list;
    (*list)->pre = newnode;
    *list = newnode;
    addDBSync(student); //call the data access layer
    logWrite("ADD; STUID:");
} //Add a student into the list

the called data access layer is here: data access

4.2.2 modify student

First find the student, then modify it.

void modifyStudentInList(int stuId, struct StudentList** list){
    //judge if the student exist in the list.
    struct StudentList* listPtr = *list;
    while (listPtr){
        if(listPtr->data.stuId == stuId){
            printf("\nstudent found, plz input the new data(except student id) "
                   "format like this(name gender age CScore EngScore):\n");
            scanf("%s %s %d %d %d",listPtr->data.name, listPtr->data.gender, &(listPtr->data.age),
                  &(listPtr->data.CScore), &(listPtr->data.EngScore));

            modifyDBSync(&(listPtr->data));
            char log2[255];
            snprintf(log2, 255, "MODIFY; STUID: %d;", stuId);
            logWrite(log2);
            return;
        }
        listPtr = listPtr->next;
    }
} //Modify student

4.2.3 delete student

First find the student, then delete it in linked list and database.

void delete(int stuId, struct StudentList** list){
    //judge if the student exist in the list.
    struct StudentList* listPtr = *list;
    while (listPtr){
        if(listPtr->data.stuId == stuId){
            printf("\nstudent found, it will be deleted ");

            if(listPtr->pre == NULL){
                *list = listPtr->next;
            } else{
                listPtr->pre->next = listPtr->next;
                listPtr->next->pre = listPtr->pre;
            }

            deleteDBSync(stuId);
            char log2[255];
            snprintf(log2, 255, "DELETE; STUID: %d;", stuId);
            logWrite(log2);
            return;
        }
        listPtr = listPtr->next;
    }
} //Delete a student from the list

4.3 Database

4.3.1 DataBase Creation

I use mySql and execute the following order:

create table students
(
	stuId int,
	name varchar(20) not null,
	gender varchar(1) default 'm' not null,
	age int default 18 null,
	CScore int null,
	EngScore int null,
	constraint students_pk
		primary key (stuId),
    check (gender = 'f' or gender = 'm'),
    check ( age>=0 and age<=100 ),
    check ( CScore>=0 and CScore<=100 ),
    check ( EngScore >=0 and EngScore<=100 )
);

And I also added some students to be the initial data.
Executed the following orders:

INSERT INTO sims.students (stuId, name, gender, age, CScore, EngScore) VALUES (18301001, 'Murray', 'f', 19, 68, 89)

INSERT INTO sims.students (stuId, name, gender, age, CScore, EngScore) VALUES (18301002, 'Adria', 'm', 20, 74, 99)

INSERT INTO sims.students (stuId, name, gender, age, CScore, EngScore) VALUES (18301003, 'Garnett', 'f', 17, 99, 100)

INSERT INTO sims.students (stuId, name, gender, age, CScore, EngScore) VALUES (18301004, 'Milford', 'm', 18, 54, 61)

INSERT INTO sims.students (stuId, name, gender, age, CScore, EngScore) VALUES (18301005, 'Megan', 'f', 17, 77, 40)

The initial database is like this:

4.3.2 Database connection

Here is the core code.

    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        finish_with_error(con);
    }
    if (mysql_real_connect(con, "localhost", "user1", "123456",
                           "sims", 0, NULL, 0) == NULL)
    {
        finish_with_error(con);
    }

4.3.3 initialize the linked list

Read from database and init the linked list. This will call data access layer to get the data.

void initializeFromDatabase(struct StudentList** list){
    struct StudentList* pointer = *list;

    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        finish_with_error(con);
    }
    if (mysql_real_connect(con, "localhost", "user1", "123456",
                           "sims", 0, NULL, 0) == NULL)
    {
        finish_with_error(con);
    }

    if (mysql_query(con, "SELECT * FROM students"))
    {
        finish_with_error(con);
    }

    MYSQL_RES *result = mysql_store_result(con);

    if (result == NULL)
    {
        finish_with_error(con);
    }

    MYSQL_ROW row;

    while ((row = mysql_fetch_row(result)))
    {
        //Each row is a student
        struct Student student;
        student.stuId = atoi(row[0]);
        strcpy(student.name, row[1]);
        strcpy(student.gender, row[2]);
        student.age = atoi(row[3]);
        student.CScore = atoi(row[4]);
        student.EngScore = atoi(row[5]);
        pointer->data = student; //Firstly, store the current student in the current node.

        //Then construct a new node for the next.
        struct StudentList* listNode = (struct StudentList*) malloc(sizeof (struct StudentList));
        listNode->pre = pointer;
        listNode->next = NULL;
        pointer->next = listNode;
        pointer = listNode;


        printf("\n");
    }
    pointer->pre->next = NULL;

    mysql_free_result(result);
    mysql_close(con);
}

4.3.4 get data

Here is the core code.

    if (mysql_query(con, "SELECT * FROM students"))
    {
        finish_with_error(con);
    }

    MYSQL_RES *result = mysql_store_result(con);

    if (result == NULL)
    {
        finish_with_error(con);
    }

    int num_fields = mysql_num_fields(result);

    MYSQL_ROW row;


    while ((row = mysql_fetch_row(result)))
    {
        for(int i = 0; i < num_fields; i++)
        {
            printf("%s ", row[i] ? row[i] : "NULL");
        }

        printf("\n");
    }

    mysql_free_result(result);

4.3.5 add database sync

To sync the data when add.

void addDBSync(struct Student* stu){
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        finish_with_error(con);
    }
    if (mysql_real_connect(con, "localhost", "user1", "123456",
                           "sims", 0, NULL, 0) == NULL)
    {
        finish_with_error(con);
    }

    char sql[255];
    snprintf(sql, 255, "INSERT INTO students VALUES(%d,'%s','%s',%d,%d,%d);",
             (*stu).stuId, (*stu).name, (*stu).gender, (*stu).age, (*stu).CScore, (*stu).EngScore);
    if (mysql_query(con, sql)){
        finish_with_error(con);
    }
    printf("inserted into the database!\n");
    mysql_close(con);
}

4.3.6 delete database sync

Functions is implemented similarly, here is the example of SQL.

delete from students where stuId = ******;

4.3.7 modify database sync

Functions is implemented similarly, here is the example of SQL.

update students set name = '%s', gender = '%s',age = %d, CScore = %d, EngScore = %d where stuId = %d;

4.3.8 sort

All sort functions are implemented similarly, here is the example of SQL.

SELECT * FROM students ORDER BY stuId;

4.3.9 log file operation

Read from file and print:

void logPrint(){
    FILE* file = fopen("log.txt","r+");
    char string[255];
    printf("\nLog: \n");
    fscanf(file,"\n%[^\n]",string);
    fscanf(file,"\n%[^\n]s",string);
    while(fscanf(file,"\n%[^\n]s",string) != EOF){
        printf("%s\n",string);
    }
    fclose(file);
} //Print the log file

Write the log to the file:

void logWrite(char* string){
    FILE* file = fopen("log.txt","a");
    time_t rawtime;
    struct tm * timeinfo;

    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
    char time[255] = {'\0'};
    strcpy(time, asctime(timeinfo));
    for(int i=0;i<255;i++){
        if (time[i] == '\n'){
            time[i] = '\0';
            break;
        }
    }
    fprintf(file,"|%s|%20s|\n",time,string);
    fclose(file);
} //Write to the log file
系统功能描述 该系统管理学生的课程信息。系统提供账户的管理和学生信息的管理功能。 系统提供的功能主要有学生信息的查询,修改,增加,删除,账户信息的查询,修改,增加,删除。 -------------------------------------------------- -------------------------------------- 登陆运行提示: -------------------------------------------------- -------------------------------------- 欢迎来到SIMS | 请选择您的帐户级别:| | [0]你是老师| [1]你是学生| [2]退出| | 选择一个数字:| -------------------------------------------------- -------------------------------------- 登录管理系统的账户分为管理员账户和普通账户: *普通用户只具有查询学生信息的功能: -------------------------------------------------- -------------------------------------- [1]搜索学生信息 [2]退出 选择一个数字: -------------------------------------------------- -------------------------------------- *管理员用户具有系统提供的所有功能: -------------------------------------------------- -------------------------------------- [1]搜索学生信息| [2]添加学生信息| [3]更新学生信息| [4]删除学生信息| [5]搜索用户帐号| [6]添加用户帐号| [7]更新用户帐号| [8]删除用户帐号| [9]退出| | 选择一个数字:| -------------------------------------------------- -------------------------------------- 系统数据主要存储在三个文件:configure.txt usr_account.txt student.txt。 usr_account.txt主要用于存放用户账户信息,0表示管理员账户,1表示普通用户 student.txt主要用于存放学生信息 configure.txt主要用于存放配置信息:usr_account.txt student.txt文件的存储位置路径信息,根据这个路径信息去读这两个文件 -------------------------------------------------- -------------------------------------- 系统在启动时会根据配置文件里的内容找到相应文件并读取出数据来加载账户信息和学生信息 SIMS用到的结构体: typedef struct user { char user_name [USER_NAME_LEN + 1]; char user_password [USER_PASSWORD_LEN + 1]; int users_limit; struct user * next; } USER_ACCOUNT,* pUSER_ACCOUNT; //注册账户信息 typedef struct course { int course_id; double course_score; }当然,* pCOURSE; //多个课程,课程结构体 typedef struct student { int stu_id; char stu_name [USER_NAME_LEN + 1]; 课程[COURSE_NUM]; 结构学生*下一个; } STUDENT,* pSTUDENT; //学生信息结构体 -------------------------------------------------- -------------------------------------- Windows下的是在Windows 10系统下的Visual Studio 2012开发的 Linux下的是在Linux ubuntu 4.10.0-42-generic#46~16.04.1-Ubuntu SMP Mon Dec 4 15:57:59 UTC 2017 x86_64 x86_64 x86_64 GNU / Linux下开发的 ****注**** windows版本随意使用; windows版本下的configure.txt和usr_account.txt student.txt在同一目录下, 要注意configure.txt内容要相应更改成这两个文件的绝对路径。 Linux的版本输入信息错误不能退格删除,只能重启;发送SIGINT信号结束进程 的Linux版本提示输入信息(任意字符)继续的时候不要输入回车,其他都行;
Sure, here's a C program that implements the student information management system with the menu interface you specified: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_STUDENTS 100 struct student { int id; char name[50]; char gender[10]; int scores[3]; int total_score; }; int read_int() { int n; while (scanf("%d", &n) != 1) { printf("Invalid input, please enter an integer: "); scanf("%*[^\n]"); } scanf("%*[^\n]"); scanf("%*c"); return n; } void read_string(char* str, int max_len) { char* p = fgets(str, max_len, stdin); if (p == NULL) { printf("Invalid input, please try again: "); read_string(str, max_len); } else { int len = strlen(str); if (len > 0 && str[len - 1] == '\n') { str[len - 1] = '\0'; } } } void enter_student_info(struct student* students, int num_students) { printf("Enter student information:\n"); for (int i = 0; i < num_students; i++) { printf("Student %d:\n", i + 1); printf(" ID: "); students[i].id = read_int(); printf(" Name: "); read_string(students[i].name, sizeof(students[i].name)); printf(" Gender: "); read_string(students[i].gender, sizeof(students[i].gender)); for (int j = 0; j < 3; j++) { printf(" Score in course %d: ", j + 1); students[i].scores[j] = read_int(); while (students[i].scores[j] < 0 || students[i].scores[j] > 100) { printf("Invalid score, please enter a score between 0 and 100: "); students[i].scores[j] = read_int(); } } students[i].total_score = students[i].scores[0] + students[i].scores[1] + students[i].scores[2]; } } void display_student_info(const struct student* students, int num_students) { printf("ID Name Gender Course 1 Course 2 Course 3 Total\n"); printf("----------------------------------------------------------------\n"); for (int i = 0; i < num_students; i++) { printf("%-5d%-19s%-8s%-9d%-9d%-9d%-5d\n", students[i].id, students[i].name, students[i].gender, students[i].scores[0], students[i].scores[1], students[i].scores[2], students[i].total_score); } } int main() { struct student students[MAX_STUDENTS]; int num_students = 0; while (1) { printf("Student information management system:\n"); printf("1) Enter student information\n"); printf("2) Display student information\n"); printf("3) Exit\n"); printf("Please enter a choice (1-3): "); int choice = read_int(); switch (choice) { case 1: printf("Enter the number of students: "); num_students = read_int(); while (num_students < 1 || num_students > MAX_STUDENTS) { printf("Invalid number of students, please enter a number between 1 and %d: ", MAX_STUDENTS); num_students = read_int(); } enter_student_info(students, num_students); printf("Student information entered successfully.\n"); break; case 2: if (num_students == 0) { printf("No student information entered yet.\n"); } else { display_student_info(students, num_students); } break; case 3: printf("Exiting...\n"); exit(0); default: printf("Invalid choice, please enter a number between 1 and 3.\n"); } } return 0; } ``` This program uses a struct to store the information of each student, and an array of structs to store the information of all students. The `read_int()` function and `read_string()` function are used for input validation, to make sure that the user enters valid integers and strings. The `enter_student_info()` function prompts the user to enter the information of each student, validates the scores, and calculates the total score. The `display_student_info()` function displays the student information in a formatted table. The `main()` function implements the menu interface and calls the other functions based on the user's choice. The program also includes some fault tolerance measures, such as checking the number of students entered, checking the validity of the scores, and handling invalid input.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值