关于C语言编写图书管理系统的一些问题,运行环境vc2010,求解答

先上代码和运行结果

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

//创建结构体及其成员
typedef struct Node {
    int num;           //编号
    char name[20];      //书名
    char author[20];    //作者
    int isexsit1;       //现存数量
    int isexsit2;       //库存数量
    struct Node *next;   //指针域
} S;     //结构体定义为S

//函数定义
void choose();
void menu();      //菜单函数
S *create();     //创建链表函数
void print(S *);      //输出链表函数
void pop_sort(S *);      //排序
void insert(S *);     //插入节点函数
void del(S *);      //删除节点函数
void search3(S *);      //编号查找

//主函数
int main() {
    choose();
}

void choose() {
    S *head;
    int n, a = 1;         
    while (a > 0) {
        menu();        //显示菜单
        printf("选择你想使用的功能:");
        scanf("%d", &n);       //选择操作
        switch (n)       //各操作数字对应菜单数字,通过n确定操作类型
        {
            case 1:      //创建
                head = create();
                break;
            case 2:     //编号查找
                search3(head);
                printf("编号\t书名\t作者\t现存数量\t库存数量\n");
                print(head);
                break;
            case 3:     //归还
                insert(head);
                printf("归还后\n");
                printf("编号\t书名\t作者\t现存数量\t库存数量\n");
                print(head);
                break;
            case 4:     //借阅
                del(head);
                printf("借阅后\n");
                printf("编号\t书名\t作者\t现存数量\t库存数量\n");
                print(head);
                break;
                default:
                a = -1;    //跳出循环条件
                break;
        }
    }
}
 
//菜单模块直接显示
void menu() {
    printf("\n\n");
    printf("\t\t   欢迎使用图书管理系统\n");
    printf("\t\t|\t1.创建图书              |\n");
    printf("\t\t|\t2.按图书编号查询        |\n");
    printf("\t\t|\t3.归还图书              |\n");
    printf("\t\t|\t4.借阅图书              |\n");
    printf("\t\t|\t5.退出程序              |\n");
    printf("\t\t|-------------------------------|\n");
    printf("\t\t\|   choice(1-5):                |\n");
}

  //创建
S *create() {
    S *head, *p, *q;    //定义指针
    int i;int num1;
    head = (S *) malloc(sizeof(S));     //头节点开辟空间
    head->next = NULL;      //置空头节点的指针域
    q = head;     //q指针记录头节点的地址
    p = head->next;      //p指针记录头节点的指针域的地址
    printf("请输入图书编号,书名,作者,现存数量,库存数量,最后输入0结束\n");
    
    scanf("%d", &num1);
    while (num1 != 0)     //输入图书编号输入为零停止循环
    {
        p = (S *) malloc(sizeof(S));     //p指针开辟空间
            //输入各成员
        p->num = num1;
        scanf("%s %s %d %d", p->name, p->author, &p->isexsit1, &p->isexsit2);
        p->next = NULL;      //置空p节点的指针域
        q->next = p;     //p,q节点连接
        q = p;      //q指针后移
        printf("请输入图书编号,书名,作者,现存数量,库存数量,最后输入0结束\n");
        scanf("%d", &num1);
    }
    return head;    //返回链表的起始地址
}

//编号查找
void search3(S *head) {
    S *p;     //定义指针
    int num1;     //定义num1用于输入查找书籍
    printf("请输入你要搜索的图书编号:");
         //输入查找编号
    scanf("%d", &num1);
    p = head->next;
    while (p != NULL) {
        if (p->num == num1)     //判断是否找到书籍
        {
                  //为真时,输出信息
            printf("书籍信息\n");
            printf("图书编号\t书名\t作者\t现存数量\t库存数量\n");
            printf("%d\t%s\t%s\t%d\t%.2f\n", p->num, p->name, p->author, p->isexsit1, p->isexsit2);
            break;
        } else
                  //为假时
            p = p->next;     //指针后移
    }
    if (p == NULL)      //查找到最后一个节点还未查到要的编号时,输出ERROR INPUT
        printf("输入错误\n");
}


//归还
void insert(S *head) {
    int i, num, flag = 1;      //flag实现判断指针是否到达最后一个节点
    S *p, *q, *r;       //定义指针便于插入操作
    printf("请输入图书的信息:\n");
    printf("请输入图书的编号,输入0结束\n");
    scanf("%d", &num);
    while (num != 0)       //输入编号不为零时循环,以零终止,可实现多个插入
    {
        r = (S *) malloc(sizeof(S));     //为r开辟空间
        r->next = NULL;     //置空r的指针域
        r->num = num;
        printf("请输入图书名,作者,现存数量,库存数量\n");
        scanf("%s %s %d %f", r->name, r->author, &r->isexsit1, &r->isexsit2);
        q = head;     //q指针记录头节点的地址
        p = head->next;     //p指针记录头节点的指针域的地址
        while (q->next != NULL && p->isexsit1 < r->isexsit1)     //循环条件:当q->next不为空,以及按现存数量排序插入
        {
            p = p->next;    //p指针后移
            q = q->next;     //q指针后移
            if (q->next == NULL)     //这个判断防止q->next为空时,在执行循环是出现野指针使程序出错
            {
                p = NULL;    //防止出现野指针p
                q->next = r;      //连接节点
                r->next = NULL;      //置空r指针域
                flag = 0;        //到达最后一个节点更改flag
                break;
            }
        } 
        if (flag)     //判断是否到达最后一个节点,为真执行该操作
        {
            r->next = p;
            q->next = r;
               //实现将r节点插入链表
        }
        printf("请输入图书编号,输入0结束\n");
        scanf("%d", &num);
    }
}

//借阅
void del(S *head) {
    S *p, *q;    //定义指针
    int b;     //用于输入编号查找删除
    p = head;     //p记录头节点的地址
    q = head->next;    //q记录头节点的指针域的地址
    printf("请输入你想要借阅的图书编号:");
      //输入编号
    scanf("%d", &b);
    while (q != NULL)   //q不为空时执行循环
    {
        if (q->num == b)   //判断是否找到输入的编号
               //为真时
        {
            p->next = q->next;    //断开q节点
            free(q);    //释放q节点neicun
            q = NULL;      //置空q指针防止出现野指针
        } else {
            //判断为假时
            p = p->next;    //p指针后移
            q = q->next;     //q指针后移
        }
    }
    if (p == NULL)    //当查找到最后一个节点还未查到要删除的编号时,输出输入错误
        printf("输入错误\n");
}
//输出链表模块
void print(S *head) {
    int i;
    S *p = head->next;
    while (p)     //当p不为空的时候执行
    {
        printf("%d\t%s\t%s\t%d\t%.2f\n", p->num, p->name, p->author, p->isexsit1, p->isexsit2);
        printf("\n");
        p = p->next;      //指针后移
    }

运行结果:

img

现在有第一个问题:想创建一个登录的功能,运行后主菜单只有1、登录和2、退出。登录成功后出现功能1到5

img

第二个问题:如何使查询后输出的结果对整齐。

求解答,谢谢了

1.再写个函数嘛,再定义一个菜单和循环,输入1才进入choose
2.有名字比较长的列,再加一个‘\t’应该可以