IO和进线程实践练习总结(IO和进线程系列学习1)

        IO和进线程系列主要总结IO和进程、线程的知识,本篇主要对嵌入式系列学习5:IO和进线程知识总结涉及到的学习内容进行实践练习,给出相应实践要求,通过知识学习,运用起来。其中包括运用标准IO实现查单词、文件IO实现加密图片、ls -l等Linux快捷命令、运用strtok函数自己实现bash的效果、通过多线程进行读写操作、进程间通信的方式实现本地聊天软件。

        整篇是本人通过学习进行笔记记载,如有不足,还请不要吝啬指出。另外我们提供嵌入式项目毕设资料与服务,远程部署、代码讲解、全方位服务。我们有专门的毕设项目辅导群(QQ:596557438),我们还有很多相关项目资料汇总,快进来瞧瞧,总有你所需!!!

涉及到的知识总结篇: 

I/O和进线程知识总结(嵌入式系列学习5)-CSDN博客

项目源码资料下载地址:箫声商城 

易学蔚来全套毕设演示(看上哪个选那个): 易学蔚来全套毕业设计汇总 · 语雀

毕设服务真实反馈,在线观看: 客户真实反馈 · 语雀

实践1:查单词

流程:

  1. 打开文件

  2. 循环

  3. 输入一个单词

  4. 遍历文件

  5. 打印出单词信息

  6. 重新开始查询

  7. 关闭文件

#include <stdio.h>
#include <string.h>
​
int main(int argc, char *argv[])
{ 
    FILE *fp =fopen("./dict.txt","r");
    if(NULL == fp)
    {
        perror("fopen failed!\n");
        return -1;
    }
​
    char let[32] = {0};
    char str[100] = {0};
    
    while(1)
    {
        printf("please input letter:");
        fgets(let,sizeof(let),stdin);
        if(let[0] == '\n' )
        {
            break;
        }
        int n = strlen(let);
        rewind(fp);
        while(1)
        {
            char *p = fgets(str,sizeof(str),fp);
            if(NULL == p)
            {
                printf("fgets failed!\n");
                break;
            }
            if(strncmp(let,str,n-1)==0)
            {
                printf("%s\n",str);
                break;
            }
            memset(str,0,sizeof(str));
        }
        memset(let,0,sizeof(let));
    }
    fclose(fp);
    return 0;
​
}

实践2:使用文件IO的函数加密图片 (音频、视频)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
​
int main(int argc, const char *argv[])
{
    if(argc!=2)
    {
        printf("%s picture\n", argv[0]);
        return -1;
    }
​
    int fd = open(argv[1], O_RDWR);
    if(fd < 0)
    {
        perror("open");
        return -1;
    }
​
    char buf[10] ={0};
​
    read(fd, buf, 10);
​
    int i;
    for(i=0; i<5; i++)
    {
        buf[i] ^= buf[9-i];
        buf[9-i] ^= buf[i];
        buf[i] ^= buf[9-i];
    }
​
    lseek(fd, 0 , SEEK_SET);
​
    write(fd, buf, 10);
​
​
    printf("加密解密成功!\n");
​
    close(fd);
​
    return 0;
}

实践3: 完成ls -l

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <time.h>
#include <sys/sysmacros.h>
#include <grp.h>
#include <dirent.h>
​
int main(int argc, const char *argv[])
{
    if(argc!=2)
    {
        printf("%s 文件路径名\n", argv[0]);
        return -1;
    }
    DIR *dirp = opendir(argv[1]);
    if(dirp == NULL)
    {
        perror("opendir failed!\n");
        return -1;
    }
    chdir(argv[1]); //改变工作目录
    while(1)
    {
        struct dirent *p= readdir(dirp);
        if( p == NULL )
        {
            break;
        }
        while(NULL != p)
        {
            if( strncmp(p->d_name, ".", 1) == 0 )
            {
                break;
            }
            struct stat mybuf;
            stat(p->d_name, &mybuf);
​
            //文件类型
​
            if(S_ISREG(mybuf.st_mode))
            {
                printf("-");
            }
            else if(S_ISDIR(mybuf.st_mode))
            {
                printf("d");
            }
            else if(S_ISCHR(mybuf.st_mode))
            {
                printf("c");
            }
            else if(S_ISBLK(mybuf.st_mode))
            {
                printf("b");
            }
            else if(S_ISFIFO(mybuf.st_mode))
            {
                printf("p");
            }
            else if(S_ISLNK(mybuf.st_mode))
            {
                printf("l");
            }
            else if(S_ISSOCK(mybuf.st_mode))
            {
                printf("s");
            }
            //文件权限
            printf("%c", (mybuf.st_mode & (0x1<<8) )?'r':'-');
            printf("%c", (mybuf.st_mode & (0x1<<7) )?'w':'-');
            printf("%c", (mybuf.st_mode & (0x1<<6) )?'x':'-');
            printf("%c", (mybuf.st_mode & (0x1<<5) )?'r':'-');
            printf("%c", (mybuf.st_mode & (0x1<<4) )?'w':'-');
            printf("%c", (mybuf.st_mode & (0x1<<3) )?'x':'-');
            printf("%c", (mybuf.st_mode & (0x1<<2) )?'r':'-');
            printf("%c", (mybuf.st_mode & (0x1<<1) )?'w':'-');
            printf("%c", (mybuf.st_mode & (0x1<<0) )?'x':'-');
​
​
​
            //链接数
            printf(" %-2ld  ", mybuf.st_nlink);
​
​
            //用户名
            struct passwd *m = getpwuid(mybuf.st_uid);
            printf(" %-5s  ", m->pw_name);
            //组名
            struct group *q = getgrgid(mybuf.st_gid);
            printf(" %-5s  ", q->gr_name);
​
            //文件大小
            printf(" %-5ld  ", mybuf.st_size);
​
            //最后一次修改的时间
​
            struct tm *k = localtime(&mybuf.st_mtime);
            printf(" %-2d %-2d %-2d:%-2d ", k->tm_mon+1,k->tm_mday,k->tm_hour,k->tm_min);
​
            //文件名
            printf("%s\n ",p->d_name);
            p = readdir(dirp);
        }
    }
    closedir(dirp);
​
    return 0;
}

实践4.1: myshell.c (自己实现 bash 的效果)

strtok();

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
​
#define N 64
​
int main(int argc, char *argv[])
{
    char buf[N] = {0};   //定义并初始化一个字符串数组
    char *arg[N];     //定义一个指针数组
    pid_t pid;
    int i = 0, j;
​
    while (1)
    {
        printf("linux@ubuntu:~$");
        fgets(buf, N, stdin);//ls -l -a   //等待用户从键盘输入,回车后将输入的内容写到buf,包括 \n,
                                          //此时,buf数组中以\0结尾,\0 前面是 \n,显然 \n 不是命令
        buf[strlen(buf)-1] = '\0';        //将buf数组中的\0前面的那个\n用\0进行覆盖
        if (strcmp(buf, "exit") == 0)     //看输入的是否为exit,注:没有对空格进行处理
            break;
​
        if ((pid = fork()) == -1)         //创建子进程
        {
            perror("fork");
            exit(-1);
        }
        if (pid == 0)
        {
        /*
            下面是利用strtok函数将buf数值进行解析,把命令和参数分别解析出来,strtok函数的使用参见
            C语言函数大全:下面是部分内容
            头文件:#include <string.h>
​
            定义函数:char * strtok(char *s, const char *delim);
​
            函数说明:strtok()用来将字符串分割成一个个片段. 参数s 指向欲分割的字符串, 参数delim 则为分割字符串,当strtok()在参数s 的字符串中发现到参数delim 的分割字符时则会将该字符改为\0 字符. 在第一次调用时,strtok()必需给予参数s 字符串, 往后的调用则将参数s 设置成NULL. 每次调用成功则返回下一个分割后的字符串指针.
​
            返回值:返回下一个分割后的字符串指针, 如果已无从分割则返回NULL.
​
            范例
            #include <string.h>
            #include <stdio.h>
            int main(void)
            {
                char s[] = "ab-cd : ef;gh :i-jkl;mnop;qrs-tu: vwx-y;z";
                char *delim = "-: ";
                char *p;
                printf("%s ", strtok(s, delim));
                while((p = strtok(NULL, delim)))
                    printf("%s ", p);
                printf("\n");
                return 0;
            }
            执行结果:
            ab cd ef;gh i jkl;mnop;qrs tu vwx y;z //-与:字符已经被\0 字符取代
​
        */
            arg[i] = strtok(buf, " ");      
            do
            {
                ++i;
                arg[i] = strtok(NULL, " ");
            }while(arg[i] != NULL);
​
            for (j = 0; j < i; j++)
                printf("%s\n", arg[j]);
​
        //    char * arg[] = {"ls", "-l", "-a", NULL};
            if (-1 == execvp(arg[0], arg)) //在子进程中调用execvp函数,子进程的三段被替换
            {
                perror("execvp");
                exit(-1);
            }
        }
        else
            wait(NULL);  //父进程等待子进程就是,即等待argv[0]中指向的命令执行完
    }
​
    return 0;
}

实践4.2:copy.c (用多线程进行读写操作)

同步和互斥都可以

第一种:运用同步信息量

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
​
sem_t sem1,sem2;
​
char buf[100] = {0};
​
int flag = 0;
​
int n = 0;
​
void *read_data(void *arg)
{
    //先读 从1.txt读取
    int fd = open("./1.txt", O_RDONLY);
    
    while(1)
    {
        sem_wait(&sem2);   //灯B -1
    
        n = read(fd, buf, sizeof(buf));
        if(n < 0)
        {
            perror("read");
            return NULL;
        }
        else if(n == 0)
        {
            flag = 1;
            close(fd);
            break;
        }   
​
        sem_post(&sem1);   //灯A +1
    }
​
}
​
void *write_data(void *arg)
{
    //再写到2.txt
    int fd = open("./2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
​
    while(1)
    {
        sem_wait(&sem1);   //灯A -1
        
        write(fd, buf, n);
        
        if(flag == 1)
        {
            close(fd);
            break;
        }
​
        sem_post(&sem2);   //灯B +1
    }
}
​
int main(int argc, const char *argv[])
{
    sem_init(&sem1, 0, 0);  //灯A
    sem_init(&sem2, 0, 1);  //灯B
​
    pthread_t tid1,tid2;
    pthread_create(&tid1, NULL, read_data, NULL);
    pthread_detach(tid1);
​
    pthread_create(&tid2, NULL, write_data, NULL);
    pthread_detach(tid2);
​
    while(1);
​
    return 0;
}
​

 第二种:运用互斥锁

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>

char buf[100] = {0};
int fd1,fd2,n=0;
pthread_mutex_t mutex; //互斥锁的变量

void *myread(void *arg)
{
    fd1 = open( "./1.txt" , O_RDONLY);
    while(1)
    {
        pthread_mutex_lock(&mutex);
        n = read(fd1, buf, sizeof(buf));
        sleep(1);
        if(n== 0)
        {
            perror("read");
            break;
        }
        pthread_mutex_unlock(&mutex);
    }

}

void *mywirte(void *arg)
{
    fd2 = open( "./2.txt" , O_WRONLY|O_CREAT|O_TRUNC, 0666);
    while(1)
    {
        write(fd2,buf,n);
        sleep(1);
    }

}

int main(int argc, const char *argv[])
{
    //初始化互斥锁
    pthread_mutex_init(&mutex, NULL);

    pthread_t tid1,tid2;

    pthread_create(&tid1, NULL, myread, NULL);
    pthread_detach(tid1);

    pthread_create(&tid2, NULL, mywirte, NULL);
    pthread_detach(tid2);

    pthread_join(tid2,NULL);
    while(1);
    return 0;
}

实践5:实现本地聊天软件(管道)

 user1:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

char buf[100] = {0};
void *write_data(void *arg)
{
    int fd = open("./f1", O_WRONLY);

    while(1)
    {
        fgets(buf,sizeof(buf),stdin);

        write(fd, buf, strlen(buf));
    }

}

void *read_data(void *arg)
{
    int fd = open("./f2", O_RDONLY);

    while(1)
    {
        read(fd, buf, sizeof(buf));

        printf("buf=%s\n", buf);

        memset(buf, 0, 100);
    }
}

int main(int argc, char *argv[])
{
    pthread_t tid1,tid2;
    pthread_create(&tid1,NULL,read_data,NULL);
    pthread_detach(tid1);

    pthread_create(&tid2,NULL,write_data,NULL);
    pthread_detach(tid2);

    while(1);    
    return 0;
}

 user2:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

char buf[100] = {0};
void *write_data(void *arg)
{
    int fd = open("./f2", O_WRONLY);
    while(1)
    {
        fgets(buf,sizeof(buf),stdin);

        write(fd, buf, strlen(buf));
    }

}

void *read_data(void *arg)
{
    int fd = open("./f1", O_RDONLY);
    while(1)
    {
        read(fd, buf, sizeof(buf));

        printf("buf=%s\n", buf);

        memset(buf, 0, 100);
    }
}

int main(int argc, char *argv[])
{
    pthread_t tid1,tid2;
    pthread_create(&tid1,NULL,read_data,NULL);
    pthread_detach(tid1);

    pthread_create(&tid2,NULL,write_data,NULL);
    pthread_detach(tid2);

    while(1);
    
    return 0;
}

持续更新中.......

更多文章,点击左上角头像,查看个人简介和更多相关项目的分享,也可通过关注我的其他平台,(嵌入式-箫声)一起学习,一起进步!Come on!!!动起手来,开始探索~~~  

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式-箫声.

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值