国庆小练习

一、二、三、四、五

一、

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

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;
}

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;
}

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

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)

二、

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

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;
}

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

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;
}

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)

三、

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

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;
}

四、

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

国庆小练习_第1张图片
国庆小练习_第2张图片
国庆小练习_第3张图片

五、

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

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;
}

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

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;
}

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)

你可能感兴趣的:(c语言)