• 国庆小练习


    一、二、三、四、五

    一、

    创建一个双向链表,
    将26个英文字母通过头插的方式插入到链表中
    通过尾删的方式将数据读取出来并删除。
    
    • 1
    • 2
    • 3

    main.c

    #include 
    #include "dblink.h"
    
    int main(int argc, const char *argv[])
    {
        dblink *h = create_head();
        for (char c = 'a'; c <= 'z'; c++)
        {
            head_insert(h, c);
            output(h);
            putchar(10);
        }
    
        for (int i = 'a'; i <= 'z'; i++)
        {
            printf("%-2c", del_end(h));
        }
        putchar(10);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    dblink.c

    #include "dblink.h"
    
    // 创建头结点
    dblink *create_head()
    {
        dblink *node = (dblink *)malloc(sizeof(dblink));
        if (NULL == node)
        {
            printf("头结点创建失败\t\t\t__%d__\n", __LINE__);
            return NULL;
        }
        node->data = 0;
        node->front = NULL;
        node->real = NULL;
        return node;
    }
    
    // 创建结点
    dblink *create_node(char data)
    {
        dblink *node = (dblink *)malloc(sizeof(dblink));
        if (NULL == node)
        {
            printf("结点创建失败\t\t\t__%d__\n", __LINE__);
            return NULL;
        }
        node->data = data;
        node->front = NULL;
        node->real = NULL;
        return node;
    }
    // 头插
    int head_insert(dblink *h, char data)
    {
        if (NULL == h)
        {
            printf("入参为空\t\t\t__%d__\n", __LINE__);
            return -1;
        }
        dblink *p = create_node(data);
        p->real = h->real;
        p->front = h;
        h->real = p;
        return 0;
    }
    // 判空
    int is_empty(dblink *h)
    {
        if (NULL == h)
        {
            printf("入参为空\t\t\t__%d__\n", __LINE__);
            return -1;
        }
        if (NULL == h->real)
        {
            return 1;
        }
        return 0;
    }
    // 尾删
    char del_end(dblink *h)
    {
        if (NULL == h)
        {
            printf("入参为空\t\t\t__%d__\n", __LINE__);
            return -1;
        }
        if (is_empty(h))
        {
            printf("这是个空链表\n");
            return -1;
        }
        dblink *p = h;
        dblink *q = p->real;
        if (NULL != q)
        {
            while (NULL != q->real)
            {
                p = q;
                q = p->real;
            }
        }
    
        p->real = NULL;
        char c = q->data;
        free(q);
        return c;
    }
    
    // 遍历输出
    int output(dblink *h)
    {
        if (NULL == h)
        {
            printf("入参为空\t\t\t__%d__\n", __LINE__);
            return -1;
        }
        dblink *p = h->real;
        while (NULL != p)
        {
            printf("%c  ", p->data);
            p = p->real;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105

    dblink.h

    #ifndef __DBLINK_H__
    #define __DBLINK_H__
    
    #include 
    
    typedef struct dblinklist
    {
        char data;
        struct dblinklist *front;   //  头
        struct dblinklist *real;    //  尾
    } dblink;
    
    dblink *create_head();
    dblink *create_node(char data);
    int head_insert(dblink *h, char data);
    int is_empty(dblink *h);
    char del_end(dblink *h);
    int output(dblink *h);
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    makefile

    EXE=dblink
    CC=gcc
    OBJs+=dblink.o
    OBJs+=main.o
    CFLAGs=-c
    
    all:$(EXE)
    $(EXE):$(OBJs)
    	$(CC) $^ -o $@
    %.o:%.c
    	$(CC) $(CFLAGs) $^ -o $@
    
    clean:
    	rm *.o $(EXE)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    二、

    用自己的代码完成
    strcpy strlen strcmp strcat函数的功能实现
    
    • 1
    • 2

    main.c

    #include 
    #include "str.h"
    int main(int argc, const char *argv[])
    {
        char s1[128] = "abcde";
        char s2[128] = "abcdef";
        printf("strcpy \n%s\n", mystrcpy(s1, s2));
    
        printf("strlen \n%ld\n", mystrlen(s1));
    
        printf("mystrcmp \n%d\n", mystrcmp(s1, s2));
    
        printf("strcat \n%s\n", mystrcat(s1, s2));
        printf("strlen \n%ld\n", mystrlen(s1));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    str.h

    #ifndef __DBLINK_H__
    #define __DBLINK_H__
    
    #include 
    
    char *mystrcpy(char *dest, const char *src);
    size_t mystrlen(const char *s);
    int mystrcmp(const char *s1, const char *s2);
    char *mystrcat(char *dest, const char *src);
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    str.c

    #include "str.h"
    char *mystrcpy(char *dest, const char *src)
    {
        int i = 0;
        while (*(dest + i) = *(src + i))
        {
            i++;
        }
        return dest;
    }
    size_t mystrlen(const char *s)
    {
        int i = 0;
        while (*(s + i) != 0)
        {
            i++;
        }
        return i;
    }
    int mystrcmp(const char *s1, const char *s2)
    {
        int i = 0;
        while (*(s1 + i) == *(s2 + i) && *(s1 + i) != 0 && *(s2 + i) != 0)
        {
            i++;
        }
        return *(s1 + i) - *(s2 + i);
    }
    char *mystrcat(char *dest, const char *src)
    {
        int i = 0;
        char *s1 = dest + mystrlen(dest);
        while (*(s1++) = *(src + i))
        {
            i++;
        }
        return dest;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    makefile

    EXE=str
    CC=gcc
    CFLAGs=-c
    OBJs+=main.o
    OBJs+=str.o
    
    all:$(EXE)
    $(EXE):$(OBJs)
    	$(CC) $^ -o $@
    %.o:%.c
    	$(CC) $(CFLAGs) $^ -o $@
    clean:
    	rm *.o $(EXE)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    三、

    完成父子进程的通信,
    父进程发送一句话后,子进程接收打印
    然后子进程发送一句话,父进程接收后打印
    
    • 1
    • 2
    • 3

    main.c

    #include 
    int main(int argc, const char *argv[])
    {
        // 父发子收
        if (mkfifo("./FtoS", 0664) < 0)
        {
            if (errno != 17)
            {
                ERR_MSG("mkfifo FtoS");
                return -1;
            }
        }
        printf("mkfifo FtoS success\n");
    
        // 子发父收
        if (mkfifo("./StoF", 0664) < 0)
        {
            if (errno != 17)
            {
                ERR_MSG("mkfifo StoF");
                return -1;
            }
        }
        printf("mkfifo StoF success\n");
    
        pid_t cpid = fork();
        if (cpid < 0)
        {
            ERR_MSG("fork");
            return -1;
        }
        else if (0 == cpid)
        {
            // 子进程
            int StoF = open("./StoF", O_WRONLY);
            if (StoF < 0)
            {
                ERR_MSG("open StoF");
                return -1;
            }
    
            int FtoS = open("./FtoS", O_RDONLY);
            if (FtoS < 0)
            {
                ERR_MSG("open FtoS");
                return -1;
            }
            char buff[128] = "";
            ssize_t res = 0;
            while (1)
            {
                bzero(buff, sizeof(buff));
                // 子收父
                res = read(FtoS, buff, sizeof(buff));
                if (res < 0)
                {
                    ERR_MSG("read");
                    return -1;
                }
                else if (0 == res)
                {
                    printf("数据读取完毕,且写端关闭\n");
                    break;
                }
                printf("父对子说 : %s\n", buff);
    
                // 子发父
                printf("子发父>>>");
                fgets(buff, sizeof(buff), stdin);
                buff[strlen(buff) - 1] = 0;
                if (write(StoF, buff, sizeof(buff)) < 0)
                {
                    ERR_MSG("write");
                    return -1;
                }
                printf("子发父成功\n");
            }
        }
        else
        {
            // 父进程
            int StoF = open("./StoF", O_RDONLY);
            if (StoF < 0)
            {
                ERR_MSG("open StoF");
                return -1;
            }
    
            int FtoS = open("./FtoS", O_WRONLY);
            if (FtoS < 0)
            {
                ERR_MSG("open FtoS");
                return -1;
            }
            char buff[128] = "";
            ssize_t res = 0;
            while (1)
            {
                // 父发子
                printf("父发子>>>");
                fgets(buff, sizeof(buff), stdin);
                buff[strlen(buff) - 1] = 0;
                if (write(FtoS, buff, sizeof(buff)) < 0)
                {
                    ERR_MSG("write");
                    return -1;
                }
    
                printf("父发子成功\n");
                // 父收子
                bzero(buff, sizeof(buff));
                res = read(StoF, buff, sizeof(buff));
                if (res < 0)
                {
                    ERR_MSG("read");
                    return -1;
                }
                else if (0 == res)
                {
                    printf("数据读取完毕,且写端关闭\n");
                    break;
                }
                printf("子对父说 : %s\n", buff);
    
            }
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129

    四、

    OSI 7层模型及每一层的功能
    绘制三次握手,四次挥手的流程图
    
    • 1
    • 2

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    五、

    结合数据库的方式完成用户注册
    客户端输入账户密码,发送给服务器
    服务器接收到账户密码后,写入到数据库中
    不允许重复注册
    
    • 1
    • 2
    • 3
    • 4

    main.c

    #include "reg.h"
    
    int main(int argc, const char *argv[])
    {
        // 打开数据库
        sqlite3 *sqldb = NULL;
        if (sqlite3_open(DB, &sqldb) != SQLITE_OK)
        {
            fprintf(stderr, "数据库打开错误 : %d : %s\t__%d__\n", sqlite3_errcode(sqldb), sqlite3_errmsg(sqldb), __LINE__);
            return -1;
        }
    
        // 创建表
        char *create_table = "CREATE TABLE if not exists register(uname char,passwd char)";
        char *err_msg = NULL;
        if (sqlite3_exec(sqldb, create_table, NULL, NULL, &err_msg) != SQLITE_OK)
        {
            fprintf(stderr, "create table : %d : %s : __%d__\n", sqlite3_errcode(sqldb), sqlite3_errmsg(sqldb), __LINE__);
            return -1;
        }
    
        char choose;
        // 操作选项
        while (1)
        {
            printf("---------------------------------------\n");
            printf("------------1. 用户注册----------------\n");
            // printf("------------2. 根据用户名注销用户----------------\n");
            // printf("------------3. 根据用户名修改密码----------------\n");
            // printf("------------4. 根据用户名查询信息----------------\n");
            printf("------------5. 查询全部信息-------------\n");
            printf("------------6. 退出--------------------\n");
            printf("---------------------------------------\n");
            printf("请选择操作 >>> ");
            choose = getchar();
            printf("choose = %c\n", choose);
            while (getchar() != 10)
                ;
            switch (choose)
            {
            case '1':
                // 增
                printf("注册\n");
                insert_into(sqldb);
                break;
            case '2':
                // 根据用户名删除
                break;
            case '3':
                // 根据用户名更改
                break;
            case '4':
                // 根据用户名查询
                break;
            case '5':
                // 查询全部用户
                find_all(sqldb);
                break;
            case '6':
                // 退出
                goto END;
            }
        }
    
    END:
        if (sqlite3_close(sqldb) != SQLITE_OK)
        {
            fprintf(stderr, "close database : %d : %s : __%d__\n", sqlite3_errcode(sqldb), sqlite3_errmsg(sqldb), __LINE__);
            return -1;
        }
    
        printf("数据库关闭成功\n");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    reg.h

    #ifndef __REG_H__
    #define __REG_H__
    
    #include 
    #define DB "register.db"
    
    int insert_into(sqlite3 *sqldb);
    int find_by_uname(sqlite3 *sqldb, char *uname);
    int find_all(sqlite3 *sqldb);
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    reg.c

    #include "reg.h"
    
    // 插入
    int insert_into(sqlite3 *sqldb)
    {
        char uname[128] = "";
        char passwd[128] = "";
        printf("请输入准备注册的用户名 >>> ");
        fgets(uname, sizeof(uname), stdin);
        uname[strlen(uname) - 1] = 0;
        // while (getchar() != 10)
        //     ;
        printf("请输入密码 >>> ");
        fgets(passwd, sizeof(passwd), stdin);
        passwd[strlen(passwd) - 1] = 0;
    
        // while (getchar() != 10)
        //     ;
        while (find_by_uname(sqldb, uname))
        {
            printf("请重新输入准备注册的用户名,输入exit取消注册 >>> ");
            fgets(uname, sizeof(uname), stdin);
            uname[strlen(uname) - 1] = 0;
            // while (getchar() != 10)
            //     ;
            if (!strcmp(uname, "exit"))
            {
                printf("退出注册\n");
                return 0;
            }
        }
        char sql_str[256] = "";
        sprintf(sql_str, "insert into register (uname,passwd) values('%s','%s');", uname, passwd);
        char *errmsg = NULL;
        printf("sql_str = %s\n", sql_str);
        if (sqlite3_exec(sqldb, sql_str, NULL, NULL, &errmsg) != SQLITE_OK)
        {
            fprintf(stderr, "insert into register : %d : %s __%d__\n", sqlite3_errcode(sqldb), errmsg, __LINE__);
            return -1;
        }
        printf("用户 [%s] 注册成功\n", uname);
        return 1;
    }
    // 根据用户名删除
    int del_by_uname()
    {
    }
    // 根据用户名更改密码
    int updata_by_uname()
    {
    }
    // 根据用户名查询
    int find_by_uname(sqlite3 *sqldb, char *uname)
    {
        char sql_str[256] = "";
        char *errmsg = NULL;
        char **pres = NULL;
        int row, colum;
        sprintf(sql_str, "select * from register where uname='%s';", uname);
        if (sqlite3_get_table(sqldb, sql_str, &pres, &row, &colum, &errmsg) != SQLITE_OK)
        {
            fprintf(stderr, "find_by_uname error : %d : %s : __%d__\n", sqlite3_errcode(sqldb), errmsg, __LINE__);
            return 0;
        }
        return row;
    }
    // 查询所有
    int find_all(sqlite3 *sqldb)
    {
        char sql_str[256] = "";
        char *errmsg = NULL;
        char **pres = NULL;
        int row, colum;
        sprintf(sql_str, "select * from register;");
        if (sqlite3_get_table(sqldb, sql_str, &pres, &row, &colum, &errmsg) != SQLITE_OK)
        {
            fprintf(stderr, "find_by_uname error : %d : %s : __%d__\n", sqlite3_errcode(sqldb), errmsg, __LINE__);
            return 0;
        }
        for (int i = 0; i <= row; i++)
        {
            for (int j = 0; j < colum; j++)
            {
                printf("%s\t", pres[(row * i) + j]);
            }
            putchar(10);
        }
        return row;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    makefile

    EXE=register
    CC=gcc
    CFLAGs=-c
    SQLITE3=-lsqlite3
    OBJs+=main.o
    OBJs+=reg.o
    all:$(EXE)
    $(EXE):$(OBJs)
    	$(CC)  $^ -o $@ $(SQLITE3)
    %.o:%.c
    	$(CC) $(CFLAGs) $^ -o $@
    clean:
    	rm *.o $(EXE)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    【数字IC验证快速入门】3、数字IC设计全流程介绍
    取代GIF?全息图成为元宇宙标配?#Looking Glass
    C# 使用Newtonsoft.Json解析嵌套json
    测试开发路线大纲与总结
    2022最新版Redis入门到精通(云课堂视频学习笔记)
    内网离线安装 Rancher 过程记录
    零束科技获得中国信通院“2022安全守卫者计划优秀案例”奖项
    大模型问答助手前端实现打字机效果
    cmake如何将源文件按照指定的组织方式进行分组,在IDE例如vistual stdio或者xcode项目工程文件中展示和管理这些源文件
    Error和Exception的关系以及区别
  • 原文地址:https://blog.csdn.net/qq_52625576/article/details/133468964