
作为高龄犬,我最近和我的大二同学一起上了一个课程(当然这是以前没有通过的). 该课程是高级语言课程设计. 高级语言是指C语言: ). 内容是制作一个XX管理系统,我选择了图书馆管理系统,首先介绍我制作的系统:
日志功能: 记录有关用户,书籍和贷款的信息的日志. 参与者: 管理员和用户. 管理员主要是指图书馆相关工作的负责人. 用户指的是可以从图书馆借书的老师或教师. 数据存储格式: 文件. 数据组织: 链表. 接口: ncurses库. 其他: CMake组织项目,GitHub版本控制: 代码地址,Linux操作系统操作.
为了表明我大学四年来一直没有白费,当然,我必须显示力量,然后从界面开始,所以我选择了终端字符库ncurses,最后的界面是像这样:
整个界面分为三部分,系统名称和时间显示在顶部,用户登录后显示用户名;左下方是整个程序的功能菜单部分;右下角是系统日志,负责动态显示添加用户,添加图书,借阅图书等操作;这三个部分负责三个线程,但是由于ncurses库本身不是线程安全的(多个线程同时运行,并且输出会出现问题),因此需要使用互斥锁来相互控制输出过程. 详细说.

(1)简介
简而言之c语言图书管理系统代码,它用于终端中,它使您可以更改字符输出位置和输出颜色并为窗口创建图形库. 有关更多介绍,请参见此处.
(2)安装
$ sudo yum install ncurses-devel //RedHat
$ sudo apt-get install libncurses5-dev libncursesw5-dev //Ubuntu
(3)使用

有关其用法,请参考以下两篇文章以及作者非常详细的代码示例,您基本上可以开始使用:
第1条: NCURSES函数的简要参考: 解释ncurses的初始化,输入和输出,颜色,窗口等.
第2条: 《 NCURSES编程指南》,中文版: 作者有许多小例子.
参考3: 代码示例
(1)ncurses图形库不是线程安全的. 先前设计的界面如下:

但是c语言图书管理系统代码,发现三个线程同时输出乱码. 最后,在stackoverflow上澄清了该问题: 确实是由线程安全性问题引起的. 最后,添加了互斥锁来解决它. 简单的代码如下:
#include <stdio.h>
#include <ncurses.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
pthread_mutex_t MUTEX; /* mutex for sync display */
#define LOCK pthread_mutex_lock(&MUTEX)
#define UNLOCK pthread_mutex_unlock(&MUTEX)
typedef struct _WIN_struct {
int startx, starty;
int height, width;
} WIN;
WIN winTitle; /* title win */
WIN winMenu; /* Main menu win */
WIN winNews; /* win news */
WINDOW *create_newwin(int height, int width, int starty, int startx) {
WINDOW *local_win;
local_win = newwin(height, width, starty, startx);
box(local_win, 0, 0);
wrefresh(local_win);
return local_win;
}
char *getTimeNow() {
time_t rawtime;
struct tm *timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
return asctime(timeinfo);
}
void *threadfunc_title(void *p) {
WINDOW *windowTitle;
LOCK;
windowTitle = create_newwin(winTitle.height, winTitle.width, winTitle.starty, winTitle.startx);
UNLOCK;
/* show title and time */
for (;;) {
sleep(1);
}
}
void *threadfunc_menu(void *p) {
WINDOW *windowMenu;
LOCK;
windowMenu = create_newwin(winMenu.height, winMenu.width, winMenu.starty, winMenu.startx);
UNLOCK;
for (;;) {
/* now do nothing */
sleep(1);
}
}
void *threadfunc_news(void *p) {
WINDOW *windowNews;
LOCK;
windowNews = create_newwin(winNews.height, winNews.width, winNews.starty, winNews.startx);
UNLOCK;
for (;;) {
sleep(1);
}
}
void initWin(WIN *p_win, int height, int width, int starty, int startx) {
p_win->height = height;
p_win->width = width;
p_win->starty = starty;
p_win->startx = startx;
}
int main(int argc, char *argv[])
{
pthread_t pidTitle;
pthread_t pidMenu;
pthread_t pidNews;
initscr();
start_color();
cbreak();
keypad(stdscr, TRUE);
noecho();
/* init location */
initWin(&winTitle, LINES*0.25, COLS, 0 , 0);
initWin(&winMenu, LINES*0.75, COLS*0.60, LINES*0.25, 0);
initWin(&winNews, LINES*0.75, COLS*0.40, LINES*0.25, COLS*0.60);
pthread_create(&pidTitle, NULL, threadfunc_title, NULL);
pthread_create(&pidMenu, NULL, threadfunc_menu, NULL);
pthread_create(&pidNews, NULL, threadfunc_news, NULL);
pthread_join(pidTitle, NULL);
pthread_join(pidMenu, NULL);
pthread_join(pidNews, NULL);
endwin();
return 0;
}
(2)而(!feof(fp))确定文件的结尾不可靠,feof(fp)确定文件的结尾指的是: 文件最后一个字符的下一个字符,用于特定参考,使用fread的缺点它的返回值无法区分它是在文件末尾还是遇到错误:

这是先前的代码:
int readUser() {
FILE *fp;
user *p = (user *) malloc(sizeof(user));
user *q = (user *) malloc(sizeof(user));
USER_HEAD = p;
USER_MAXID = -1;
fp = fopen(USER_PATH, "r+");
if (fp == NULL) {
fp = fopen(USER_PATH, "w+");
free(q);
return 0;
}
while (!feof(fp)) {
fscanf(fp, "%d %s %s %s %s %d\n", &(q->user_id), q->user_stid,
q->user_name, q->user_address, q->user_mail, &(q->user_status));
/* update USER_MAXID*/
if (q->user_id > USER_MAXID) {
USER_MAXID = q->user_id;
}
p->next = q;
p = q;
q = (user *) malloc(sizeof(user));
}
p->next = NULL;
free(q);
fclose(fp);
return 0;
}
最后使用read进行读取,添加O_CREATE也可以防止文件不存在:
int readUser() {
int fd;
int size;
user *p = (user *) malloc(sizeof(user));
user *q = (user *) malloc(sizeof(user));
USER_HEAD = p;
USER_MAXID = 0;
fd = open(USER_PATH, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR);
if (fd == -1) {
perror("open");
exit(1);
}
while ((size = read(fd, q, sizeof(user))) != 0) {
if (q->user_id > USER_MAXID) {
USER_MAXID = q->user_id;
}
p->next = q;
p = q;
q = (user *) malloc(sizeof(user));
}
p->next = NULL;
free(q);
close(fd);
return 0;
}
(3)如何使用C语言获取系统时间: localtime()和asctime()返回的字符串将包含\ n,这不是非常友好,这可能是历史原因,具体参考: 封装一个并删除它\ n个字符,代码如下:
char *getTimeNow() {
char *timestr;
time_t rawtime;
struct tm *timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
timestr = asctime(timeinfo);
/* del \n */
timestr[strlen(timestr) - 1] = '\0';
return timestr;
}
[结束]
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-263264-1.html
也要拿回来
还有一点没吃过这种芝麻糊不知道的是
放弃那些陈旧的