一、makefile
hello_test:main.o menu.o login.o input.o show.o order.o delete.o modify.o insert.o search.o total.o
gcc main.o menu.o login.o input.o show.o order.o delete.o modify.o insert.o search.o total.o -o hello_test
main.o:main.c
gcc -c main.c -o main.o
menu.o:menu.c
gcc -c menu.c -o menu.o
login.o:login.c
gcc -c login.c -o login.o
input.o:input.c
gcc -c input.c -o input.o
show.o:show.c
gcc -c show.c -o show.o
order.o:order.c
gcc -c order.c -o order.o
delete.o:delete.c
gcc -c delete.c -o delete.o
modify.o:modify.c
gcc -c modify.c -o modify.o
insert.o:insert.c
gcc -c insert.c -o insert.o
search.o:search.c
gcc -c search.c -o search.o
total.o:total.c
gcc -c total.c -o total.o
二、模块代码
我把整个系统分为两大块,一个是登录,一个是操作。数了一下总共有11个.c文件。
1、main.c
/********************
file name:main.c
function:main
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include <stdio.h>
#include <stdlib.h>
#include "menu.h"
#include "login.h"
#include "input.h"
#include "show.h"
#include "order.h"
#include "delete.h"
#include "modify.h"
#include "insert.h"
#include "search.h"
#include "total.h"
#include "user.h"
int main(int argc, char *argv[]) {
char *userfile = "users.txt";
int choice, userType, n;
char *filename = "data.txt";
// 检查命令行参数数量
if (argc < 3) {
fprintf(stderr, "Usage: %s <username> <password>\n", argv[0]);
exit(EXIT_FAILURE);
}
char *username = argv[1];
char *password = argv[2];
userType = login(userfile, username, password);
if (userType == -1) {
// 登录失败,退出程序
return EXIT_FAILURE;
}
do {
menu(userType); // 根据用户类型显示菜单
scanf("%d", &n);
getchar();
switch (n) {
case 1: show(filename); break;
case 2: order(filename); break;
case 3: modify(filename); break;
case 4: insert(filename); break;
case 5: in(filename); break;
case 6: search(filename); break;
case 7: total(filename); break;
case 8: del(filename); break;
default: break;
}
} while (n != 0);
return 0;
}
2、login.c
/********************
file name:input.c
function:add student record
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include "user.h"
#define LAN sizeof(User)
User users[MAX_USERS] = {
{"s", "1", 0},
{"t", "2", 1}
};
int userCount = 2; // 初始化用户数量
int login(char *userfile, char *username, char *password) {
int m = 0;
int fd;
char ch[2], newPass[50];
ssize_t bytes_read;
off_t offset = 0;
int userFound = 0; // 标记是否找到用户
// 打开文件用于读写
if ((fd = open(userfile, O_RDWR)) == -1) {
perror("can not open file");
return -1;
}
// 读取文件中的所有记录到users数组
while ((bytes_read = read(fd, &users[m], LAN)) == LAN) {
m++;
}
close(fd);
// 检查用户名和密码
for (int i = 0; i < m; i++) {
if (strcmp(users[i].username, username) == 0 && strcmp(users[i].password, password) == 0) {
userFound = 1;
printf("Whether to change the password?(y/n):");
scanf("%1s", ch); // 使用 %1s 避免缓冲区溢出
if (ch[0] == 'Y' || ch[0] == 'y') {
printf("please input new password:");
scanf("%49s", newPass); // 使用 %49s 限制密码长度
strcpy(users[i].password, newPass);
// 重新打开文件用于写入
if ((fd = open(userfile, O_WRONLY | O_TRUNC)) == -1) {
perror("Cannot open file for writing");
return -1;
}
// 写入所有记录,包括已修改的记录
for (int j = 0; j < m; j++) {
if (write(fd, &users[j], LAN) != LAN) {
perror("Error writing file");
}
}
close(fd);
printf("Modify password successfully!\n");
}
// 登录成功后返回用户类型
return users[i].userType;
}
}
if (!userFound) {
printf("Login error\n");
}
return -1;
}
3、delete.c
/********************
file name:delete.c
function:delete student record
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include "student.h"
void del(char *filename)
{
int fd, i, j, m = 0;
int snum;
char ch[2];
ssize_t bytes_read;
off_t offset = 0;
// Open the file in read/write mode
if ((fd = open(filename, O_RDWR)) == -1) {
perror("Can not open file");
return;
}
// Read all records into stu array
while ((bytes_read = read(fd, &stu[m], LEN)) == LEN) {
m++;
}
close(fd); // Close the file to reopen it later
if (m == 0) {
printf("No record!\n");
return;
}
printf("Please input the number: ");
scanf("%d", &snum);
for (i = 0; i < m; i++) {
if (snum == stu[i].num) {
break;
}
}
if (i < m) {
printf("Find the student, delete? (y/n): ");
scanf("%s", ch);
if (strcmp(ch, "Y") == 0 || strcmp(ch, "y") == 0) {
for (j = i; j < m - 1; j++) {
stu[j] = stu[j + 1]; // Shift records to overwrite the deleted one
}
m--; // Decrease the total number of records
}
} else {
printf("Student not found.\n");
return;
}
// Reopen the file in write-binary mode to rewrite the updated data
if ((fd = open(filename, O_WRONLY | O_TRUNC)) == -1) {
perror("Can not open file for writing");
return;
}
for (j = 0; j < m; j++) {
if (write(fd, &stu[j], LEN) != LEN) {
perror("Can not save!");
close(fd);
return;
}
}
close(fd);
printf("Delete successfully!\n");
}
4、input.c
/********************
file name:input.c
function:add student record
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include"student.h"
#include"show.h"
void in(char *filename)
{
int i, m = 0;
int fd;
char ch[2];
ssize_t bytes_read;
off_t offset = 0;
// Open the file in read/write mode to get current records
if ((fd = open(filename, O_RDWR)) == -1) {
perror("Can not open file");
return;
}
// Read all records into stu array
while ((bytes_read = read(fd, &stu[m], LEN)) == LEN) {
m++;
}
close(fd); // Close the file to reopen it later
if (m == 0) {
printf("No record!\n");
} else {
system("clear"); // Clear screen
show(); // Display existing records
}
// Reopen the file in write-binary mode to write new records
if ((fd = open(filename, O_WRONLY)) == -1) {
perror("Can not open file for writing");
return;
}
// Write existing records back to the file
for (i = 0; i < m; i++) {
if (write(fd, &stu[i], LEN) != LEN) {
perror("Can not save!");
close(fd);
return;
}
}
printf("Please input (y/n): ");
scanf("%s", ch);
while (strcmp(ch, "Y") == 0 || strcmp(ch, "y") == 0) {
printf("Number: ");
scanf("%d", &stu[m].num);
// Check if the number already exists
for (i = 0; i < m; i++) {
if (stu[i].num == stu[m].num) {
printf("The number is existing, press any key to continue!\n");
getchar();
close(fd);
return;
}
}
printf("Name: ");
scanf("%s", stu[m].name);
printf("Chinese: ");
scanf("%lf", &stu[m].elec);
printf("Math: ");
scanf("%lf", &stu[m].expe);
printf("English: ");
scanf("%lf", &stu[m].requ);
stu[m].sum = stu[m].elec + stu[m].expe + stu[m].requ;
// Write new record to the file
if (write(fd, &stu[m], LEN) != LEN) {
perror("Can not save!");
getchar();
} else {
printf("%s saved!\n", stu[m].name);
m++;
}
printf("Continue? (y/n): ");
scanf("%s", ch);
}
close(fd);
printf("OK!\n");
}
5、insert.c
这个插入的功能我试了几次感觉没什么用,但是没有删掉。
/********************
file name:insert.c
function:insert new record
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include "student.h"
void insert(char *filename)
{
int i, j, k, m = 0, snum;
int fd, new_fd;
ssize_t bytes_read;
off_t offset = 0;
struct student temp_stu;
// Open the file in read-only mode to read current records
if ((fd = open(filename, O_RDONLY )) == -1) {
perror("Can not open file");
exit(EXIT_FAILURE);
}
// Read all records into stu array
while ((bytes_read = read(fd, &stu[m], LEN)) == LEN) {
m++;
}
close(fd); // Close the file to reopen it later
if (m == 0) {
printf("No record!\n");
return;
}
printf("Please input position where do you want to insert! (input the number)\n");
scanf("%d", &snum);
// Check if the position exists
for (i = 0; i < m; i++) {
if (snum == stu[i].num) {
break;
}
}
if (i == m) {
printf("Position does not exist!\n");
return;
}
// Shift records to make space for the new record
for (j = m; j > i; j--) {
stu[j] = stu[j - 1];
}
printf("Now please input the new information.\n");
printf("Number: ");
scanf("%d", &stu[i].num);
// Check if the number already exists
for (k = 0; k < m + 1; k++) {
if (stu[k].num == stu[i].num && k != i) {
printf("The number is existing, press any key to continue!\n");
getchar();
return;
}
}
printf("Name: ");
scanf("%s", stu[i].name);
printf("Chinese: ");
scanf("%lf", &stu[i].elec);
printf("Math: ");
scanf("%lf", &stu[i].expe);
printf("English: ");
scanf("%lf", &stu[i].requ);
stu[i].sum = stu[i].elec + stu[i].expe + stu[i].requ;
// Create a temporary file to write updated records
if ((new_fd = creat(filename, S_IRUSR | S_IWUSR)) == -1) {
perror("Can not create temporary file");
exit(EXIT_FAILURE);
}
// Write updated records to the temporary file
for (k = 0; k <= m; k++) {
if (write(new_fd, &stu[k], LEN) != LEN) {
perror("Can not save!");
close(new_fd);
unlink("temp_filename"); // Remove temporary file on error
exit(EXIT_FAILURE);
}
}
close(new_fd);
// Replace original file with the temporary file
if (rename("temp_filename", "filename") == -1) {
perror("Can not rename file");
unlink("temp_filename"); // Remove temporary file on error
exit(EXIT_FAILURE);
}
printf("Save successfully!\n");
}
6、menu.c
/********************
file name:menu.c
function:show user's work
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include<stdio.h>
#include<string.h>
#include"login.h"
void menu(int userType) {
if(userType == 0)
{
printf("\n\n\n\n\n");
printf("\t\t|---------------------STUDENT-------------------|\n");
printf("\t\t|\t 0. exit |\n");//退出
printf("\t\t|\t 1. show |\n");//显示
printf("\t\t|\t 2. order |\n");//排序
printf("\t\t|-----------------------------------------------|\n\n");
printf("\t\t\tchoose(0-2):");
}
else if(userType == 1)
{
printf("\n\n\n\n\n");
printf("\t\t|---------------------STUDENT-------------------|\n");
printf("\t\t|\t 0. exit |\n");
printf("\t\t|\t 1. show |\n");
printf("\t\t|\t 2. order |\n");
printf("\t\t|\t 3. modify record |\n");
printf("\t\t|\t 4. insert record |\n");
printf("\t\t|\t 5. input record |\n");
printf("\t\t|\t 6. search record |\n");
printf("\t\t|\t 7. number |\n");
printf("\t\t|\t 8. delete record |\n");
printf("\t\t|-----------------------------------------------|\n\n");
printf("\t\t\tchoose(0-8):");
}
}
7、modify.c
/********************
file name:modify.c
function:modify student record
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include "student.h"
#include <stdlib.h>
#include <stdbool.h>
void modify(char *filename)
{
int fd, i, m = 0, snum;
bool found = false;
ssize_t bytes_read;
off_t offset = 0;
// Open the file in read-write mode to read current records
if ((fd = open(filename, O_RDWR)) == -1) {
perror("Cannot open file");
return;
}
// Read all records into stu array
while ((bytes_read = read(fd, &stu[m], LEN)) == LEN) {
m++;
}
close(fd); // Close the file to reopen it later
if (m == 0) {
printf("No record!\n");
return;
}
printf("Please input the number of the student you want to modify!\n");
scanf("%d", &snum);
// Find the student
for (i = 0; i < m; i++) {
if (snum == stu[i].num) {
found = true;
break;
}
}
if (!found) {
printf("Student not found!\n");
return;
}
printf("Find the student! You can modify!\n");
printf("Name:\n");
scanf("%s", stu[i].name); // Input name
printf("\nChinese:\n");
scanf("%lf", &stu[i].elec); // Input Chinese score
printf("Math:\n");
scanf("%lf", &stu[i].expe); // Input Math score
printf("English:\n");
scanf("%lf", &stu[i].requ); // Input English score
stu[i].sum = stu[i].elec + stu[i].expe + stu[i].requ;
// Reopen the file in read-write mode to write updated records
if ((fd = open(filename, O_RDWR )) == -1) {
perror("Cannot open file for writing");
return;
}
// Rewrite all records, including the modified one
for (i = 0; i < m; i++) {
if (write(fd, &stu[i], LEN) != LEN) {
perror("Error writing file");
close(fd);
return;
}
}
close(fd);
printf("Save successfully\n");
}
8、order.c
/********************
file name:order.c
function:order student's num
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include "student.h"
void order(char *filename)
{
struct student *students = malloc(10 * LEN); // Allocate memory for 10 students
if (students == NULL) {
printf("Memory allocation failed!\n");
return;
}
size_t m = 0; // Number of students read
size_t capacity = 10; // Initial capacity set to 10
struct student t; // Temporary variable for swapping
// Open file in read-only binary mode
int fd = open(filename, O_RDONLY);
if (fd == -1) {
perror("Cannot open file");
free(students);
return;
}
// Dynamically read all records into students array
while (1) {
ssize_t bytesRead = read(fd, &t, LEN);
if (bytesRead == -1) {
perror("Error reading file");
close(fd);
free(students);
return;
} else if (bytesRead == 0) {
break;
}
if (m >= capacity) {
// Need more space, reallocate memory
struct student *newStudents = realloc(students, (capacity + 10) * LEN);
if (newStudents == NULL) {
printf("Memory allocation failed!\n");
close(fd);
free(students);
return;
}
students = newStudents;
capacity += 10;
}
// Copy read data to the array
memcpy(&students[m], &t, LEN);
m++;
}
close(fd); // Close file
// Sort using bubble sort algorithm
for (size_t i = 0; i < m - 1; i++)
for (size_t j = i + 1; j < m; j++)
if (students[i].sum < students[j].sum) {
t = students[i];
students[i] = students[j];
students[j] = t;
}
// Reopen file and write sorted data
fd = open(filename, O_WRONLY | O_TRUNC);
if (fd == -1) {
perror("Cannot open file for writing");
free(students);
return;
}
for (size_t i = 0; i < m; i++) {
if (write(fd, &students[i], LEN) != LEN) {
perror("Error writing file");
close(fd);
free(students);
return;
}
}
close(fd); // Close file
free(students); // Free dynamically allocated memory
printf("Save successfully\n");
getchar();
}
9、search.c
/********************
file name:search.c
function:search number
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include "student.h"
#include <stdbool.h>
void search(char *filename)
{
int fd;
int snum, i, m = 0;
char ch;
bool found = false;
// Open the file in read-only binary mode
if ((fd = open(filename, O_RDONLY)) == -1)
{
perror("Can not open file!");
return;
}
/* 读取所有记录到stu数组 */
while (read(fd, &stu[m], LEN) == LEN)
m++;
close(fd);
if (m == 0)
{
printf("No record!\n");
return;
}
printf("Please input the number: ");
scanf("%d", &snum);
/* 查找输入的学号是否在记录中 */
for (i = 0; i < m; i++)
{
if (snum == stu[i].num)
{
printf("Find the student, show? (y/n): ");
scanf(" %c", &ch); // 注意这里使用%c和空格处理输入
if (ch == 'y' || ch == 'Y')
{
printf("Number Name Chinese Math English Sum\n");
printf(FORMAT, DATA);
found = true;
break;
}
}
}
if (!found)
{
printf("Can not find the student!\n");
}
}
10、show.c
/********************
file name:show.c
function:show all record
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include "student.h"
void show(char *filename)
{
int fd; // File descriptor
int i, m = 0;
off_t offset = 0; // Offset for lseek()
// Open the file in read-only binary mode
if ((fd = open(filename, O_RDONLY)) == -1)
{
perror("Can not open file!");
return;
}
/* 读取所有记录到stu数组 */
while (read(fd, &stu[m], LEN) == LEN)
{
m++;
}
printf("Number Name Chinese Math English Sum\n");
for (i = 0; i < m; i++)
{
printf(FORMAT, DATA);
}
close(fd);
}
11、total.c
/********************
file name:total.c
function:count students
return value:
participation:
author:Gaoyuying
creation time:2024/07/03
********************/
#include "student.h"
void total(char *filename)
{
int fd;
int m = 0;
// Open the file in read-only binary mode
if ((fd = open(filename, O_RDONLY)) == -1)
{
perror("Can not open file!");
return;
}
/* 统计记录个数即学生个数 */
while (read(fd, &stu[m], LEN) == LEN)
m++;
if (m == 0)
{
printf("No record!\n");
}
else
{
printf("The class has %d students!\n", m);
}
close(fd);
}
三、.h头文件
以上就是所有的代码了,然后.h文件可以模仿这样写
#ifndef STUDENT_H
#define STUDENT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#define LEN sizeof(struct student)
#define FORMAT "%-8d%-15s%-12.1lf%-12.1lf%-12.1lf%-12.1lf\n"
#define DATA stu[i].num,stu[i].name,stu[i].elec,stu[i].expe,stu[i].requ,stu[i].sum
struct student/*定义学生成绩结构体*/
{ int num;/*学号*/
char name[15];/*姓名*/
double elec;/*语文*/
double expe;/*数学*/
double requ;/*英语*/
double sum;/*总分*/
};
struct student stu[100];/*定义结构体数组*/
#endif
有其他问题可以私信或者评论区,我看到了就会回。