【嵌入式Linux笔记】02--系统IO 、标准IO、目录操作

本文内容:系统IO 、标准IO、目录操作

 

  • linux文件IO

1.课程概览
  核心内容:使用linux中提供一系列函数(API),去操作linux当中的文件
            (新建文件、打开文件、读写文件、关闭文件)
  我们发现前面我已经学过如何操作文件:
            使用命令来操作:vi  touch  gedit vim
            使用函数接口来写代码进行操作:
            
2.基本概念
       1.在linux中一切都是文件
               对于操作系统来说:硬件设备-----》只使用驱动(可执行的二进制文件)
            既然所有的东西都可以抽象为文件,我们很有必有学习文件IO.
       2.linux中对文件的分类  ls -l查看的
           普通文件       -
           目录文件       d(directory)
           软连接文件     l(link)
           管道文件       p(pipe)  进程间通信
           套接字文件     s(socket)网络通信
           字符设备文件   c          驱动
           块设备文件     b          驱动(U盘、硬盘)

3.相关的接口函数----》man手册----》按字母‘q’退出手册    
       1   Executable programs or shell commands//linux的系统命令
       2   System calls (functions provided by the kernel)//linux内核提供的函数
       3   Library calls (functions within program libraries)//C语言库函数
        

  (1)系统IO(操作系统提供的函数)
           1.1文件的打开和新建----》open()
        头文件:#include <sys/types.h>
                #include <sys/stat.h>
                #include <fcntl.h>
        函数原型:
        int open(const char *pathname, int flags);
        函数返回值:
                 成功   返回一个文件描述符(替身)>=0
                 失败   返回 -1 
        函数参数:const char *pathname --->你要打开的文件所在的位置
                  int flags(宏定义)---》O_RDONLY  read  只读权限
                                        O_WRONLY  write 只写权限
                                        O_RDWR    read and write 可读可以
                                        O_CREAT   creat  新建一个文件
                                        O_EXCL    跟O_CREAT配合,如果有新建文件的时候,文件存在,就退出
                                        O_NOCTTY  无权限默认属性
                                        O_TRUNC   跟O_CREAT配合,如果有新建文件的时候,文件存在,就覆盖                                 
       
       int open(const char *pathname, int flags, mode_t mode);
            
            形参:mode
               注意:权限mode满足这个公式 mode & ~umask
                     设置权限只能在纯粹的linux环境使用才能生效
             用户组
              S_IRWXU  00700 user has  read,  write  and  execute permission
              S_IRUSR  00400 user has read permission
              S_IWUSR  00200 user has write permission
              S_IXUSR  00100 user has execute permission
             同组用户
              S_IRWXG  00070 group has read, write and execute permission
              S_IRGRP  00040 group has read permission
              S_IWGRP  00020 group has write permission
              S_IXGRP  00010 group has execute permission
             其他组
              S_IRWXO  00007 others have read, write and execute permission
              S_IROTH  00004 others have read permission
              S_IWOTH  00002 others have write permission
              S_IXOTH  00001 others have execute permission
        
        1.2 错误码---》在linux中定义一个int类型的全局变量叫errno, 保存的是所有错误对应的编号
         补充:find / -name errno.h(在根目录下面寻找一个名字叫做errno.h文件)              

            我们的前辈将所有文件IO中产生的错误全部罗列,采用宏定义表述错误
             头文件:/usr/include/asm-generic/errno.h

            perror()--->帮助我们将错误的原因打印出来
            头文件:#include <stdio.h>

             void perror(const char *s);//参数为字符串
        
        1.3文件的读写  read()  write()
           头文件:#include <unistd.h>
           函数原型:
           ssize_t read(int fd, void *buf, size_t count);
           返回值:成功  返回成功读取的字节数
                  失败  返回 -1
                   0    文件读完了
                   
          函数参数:int fd       -----》你要读取的文件的描述符
                    void *buf    -----》储存你读取的内容
                    size_t count -----》你打算读取多少个字节的数据

           头文件:#include <unistd.h>
           函数原型:
           ssize_t write(int fd, const void *buf, size_t count);
           返回值:成功  返回成功写入的字节数
                   失败  返回 -1
                   0    文件写完了
            函数参数:int fd             -----》你要写入的文件的描述符
                      const void *buf    -----》储存你写入的内容
                      size_t count       -----》你打算写入多少个字节的数据
           
           清空写入的操作:bzero
            头文件:#include <strings.h>
            函数原型:
            void bzero(void *s, size_t n);
            参数:void *s   -----》你要清空的对象
                  size_t n  -----》你要清空的空间大小
        
        1.4文件的关闭 close()
           #include <unistd.h>

           int close(int fd);
           返回值:成功  返回 0
                   失败  返回 -1
            参数:int fd  ---》你打算关闭的文件描述符

/*
    打开文件且只读
*/
#include "myhead.h"

int main(void)
{
	int fd;//文件描述符
	//打开文件,打开当前路径下已经存在文件
	fd=open("./2.txt",O_RDONLY);
	if(fd == -1)
	{
		printf("open 1.txt false!\n");
		return -1;//条件有问题异常退出
	}
	
	return 0;
}
/*
    创建文件并打开
*/
#include "myhead.h"

int main(void)
{
	int fd;//文件描述符
	//打开并创建文件,在当前路径下创建文件
	fd=open("./2.txt",O_CREAT | O_TRUNC |O_RDWR);
	if(fd == -1)
	{
		printf("open 1.txt false!\n");
		return -1;//条件有问题异常退出
	}
	
	return 0;
}

  

/*
    创建一个文件并且赋权限
*/
#include "myhead.h"

int main(void)
{
	int fd;//文件描述符
	//创建一个3.txt并且将权限改为666
	//fd=open("./3.txt",O_CREAT | O_TRUNC ,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);//啰嗦写法
	fd=open("./3.txt",O_CREAT | O_TRUNC |O_RDWR,0666);
	if(fd == -1)
	{
		printf("create 3.txt false!\n");
		return -1;//条件有问题异常退出
	}
	
	return 0;
}
/*
    perror错误打印
*/
#include "myhead.h"

int main(void)
{
	int fd;//文件描述符
	//打开当前目录下已经存在1.txt,但是1.txt文件权限为只读,我想让它可读可写(矛盾)
	fd=open("./1.txt",O_RDWR);
	if(fd == -1)
	{
		printf("create 3.txt false!,errno is %d\n",errno);
		perror("create 3.txt false!");
		return -1;//条件有问题异常退出
	}
	
	return 0;
}
/*
      拷贝文件1的内容到文件2
       实现 ./my_cp   1.txt  2.txt
       判断下参数个数    
    
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <unistd.h>

#include <strings.h>
int main(int argc, char const *argv[])
{
	int fd1,fd2;
	char buf[50];
	char buf1[50];
	bzero(buf,50);
	bzero(buf1,50);
	fd1=open(argv[1],O_RDWR);
	fd2=open(argv[2],O_RDWR);
	if(fd1==-1||fd2==-1)
	{
		perror("open false!\n");
		return -1;
	}
	printf("argc:%d\n",argc);
	read(fd1,buf,50);
	write(fd2,buf,50);
	close(fd1);
	close(fd2);
	
	fd1=open(argv[1],O_RDWR);
	fd2=open(argv[2],O_RDWR);
	read(fd1,buf,50);
	read(fd2,buf1,50);
	printf("1.txt:%s\n",buf1);
	printf("2.txt:%s\n",buf1);
	close(fd1);
	close(fd2);
}

1.5 设置文件的读写偏移(光标) lseek()
     头文件: #include <sys/types.h>
              #include <unistd.h>
     函数原型:
       off_t lseek(int fd, off_t offset, int whence);
      返回值:成功 返回文件当前位置距离文件开头的字节数  
              失败 返回 -1
     函数参数:int fd       ----》你要设置读写偏移的那个文件的文件描述符
               off_t offset ----》你打算偏移多少个字节
               int whence   ----》你打算偏移位置
                                  SEEK_SET  文件的开头
                                  SEEK_CUR  当前的位置
                                  SEEK_END  文件的末尾
                lseek(fd,-2,SEEK_SET);//不起作用,还是停留在起始位置
                lseek(fd,2,SEEK_SET);//从开头往后挪动2个字节
                lseek(fd,-2,SEEK_CUR);//从当前位置往前挪动2个字节
                lseek(fd,2,SEEK_CUR);//从当前位置往后挪动2个字节
                lseek(fd,-2,SEEK_END);//从末尾位置往前挪动2个字节
                lseek(fd,2,SEEK_END);//从末尾位置往后挪动2个字节
        off_t ret=lseek(fd,0,SEEK_END);    //返回值就表示文件大小  

 

#include "myhead.h"

int main(void)
{
	int fd;//文件描述符
	int ret1,ret2;
	char buf[50];
	char buf1[]="helloworld";
	bzero(buf,50);
    //打开你要读写的文件
	fd=open("./2.txt",O_RDWR);
	if(fd == -1)
	{
		perror("open 1.txt flase!\n");//打印错误提示
		return -1;//异常退出
	}
	//给文件写入数据
	ret2=write(fd,buf1,sizeof(buf1));
	if(ret2 == -1)
	{
		perror("写失败\n");
		return -1;
	}
	lseek(fd,0,SEEK_SET);
	close(fd);
	fd=open("./2.txt",O_RDWR);
	//while(1)
	//{ 
        
        ret1=read(fd,buf,10);
		/* if(ret1 ==0)//说明文件读完
	     break; */
	//}
	printf("我读取到的内容是%s\n",buf);
	close(fd);
	return 0;
}

   1.6获取文件属性  stat()  man 3 stat
     文件的属性:大小,文件类型,名称,日期,所有者,权限
      头文件:#include <sys/stat.h>
      函数原型:
       int stat(const char *restrict path, struct stat *restrict buf);
      返回值:  成功  返回 0
                失败  返回 -1
      函数参数:const char *restrict path----》文件的路径
                struct stat *restrict buf----》存放你获取到的文件属性
   
    struct stat 
    {
       dev_t     st_dev;     /* 设备文件的编号 */
       ino_t     st_ino;     /* 节点编号 */
       mode_t    st_mode;    /* 文件的权限*/
       nlink_t   st_nlink;   /* 硬链接数*/
       uid_t     st_uid;     /* 用户组ID*/
       gid_t     st_gid;     /* 同组用户ID*/
       dev_t     st_rdev;    /* 设备ID (if special file) */
       off_t     st_size;    /* 文件大小,文件字节*/
       blksize_t st_blksize; /* 块设备文件大小 */
       blkcnt_t  st_blocks;  /* 512B块设备大小 */
       time_t    st_atime;   /* 上次访问时间 */
       time_t    st_mtime;   /* 上次修改时间 */
       time_t    st_ctime;   /* 上次状态改变时间*/
    };
    访问头文件路径:/usr/include/linux/stat.h
    用于判断文件类型的宏定义
    判断是否为链接文件
    #define S_ISLNK(m)    (((m) & S_IFMT) == S_IFLNK)
    判断是否为普通文件
    #define S_ISREG(m)    (((m) & S_IFMT) == S_IFREG)
    判断是否为目录文件
    #define S_ISDIR(m)    (((m) & S_IFMT) == S_IFDIR)
    判断是否为字符块设备文件
    #define S_ISCHR(m)    (((m) & S_IFMT) == S_IFCHR)
    判断是否为块设备文件
    #define S_ISBLK(m)    (((m) & S_IFMT) == S_IFBLK)
    判断是否为管道文件
    #define S_ISFIFO(m)    (((m) & S_IFMT) == S_IFIFO)
    判断是否为套接字文件
    #define S_ISSOCK(m)    (((m) & S_IFMT) == S_IFSOCK)
    用户
    #define S_IRWXU 00700
    #define S_IRUSR 00400
    #define S_IWUSR 00200
    #define S_IXUSR 00100
    同组
    #define S_IRWXG 00070
    #define S_IRGRP 00040
    #define S_IWGRP 00020
    #define S_IXGRP 00010
    其他
    #define S_IRWXO 00007
    #define S_IROTH 00004
    #define S_IWOTH 00002
    #define S_IXOTH 00001

/*
    文件属性
*/
#include "myhead.h"

int main(void)
{
	int ret;
	struct stat mystat;
	//获取当前路径下1.txt文件属性
	ret=stat("1.txt",&mystat);
	if(ret == -1)
	{
		perror("get file stat failed!\n");
		return -1;
	}
	//打印文件属性
	printf("文件的大小:%ld\n",mystat.st_size);
	printf("文件的权限:%o\n",mystat.st_mode);
	//判断文件类型
	if(S_ISREG(mystat.st_mode))
	{
		printf("1.txt 普通文件\n");
	}
	if(S_ISDIR(mystat.st_mode))
	{
		printf("1.txt 目录文件\n");
	}
	//判断文件权限
	if(((mystat.st_mode) & S_IFMT) == S_IRUSR)
	{
		printf("当前用户对于1.txt来说是可读的\n");
	}
	if(((mystat.st_mode) & S_IFMT) == S_IWUSR)
	{
		printf("当前用户对于1.txt来说是可写的\n");
	}
	if(((mystat.st_mode) & S_IFMT) == S_IXUSR)
	{
		printf("当前用户对于1.txt来说是可执行\n");
	}
	return 0;
}
/*
    文件权限
*/
#include "myhead.h"

int main(void)
{
	int ret;
	struct stat mystat;
	//获取当前路径下1.txt文件属性
	ret=stat("1.txt",&mystat);
	if(ret == -1)
	{
		perror("get file stat failed!\n");
		return -1;
	}
	//打印文件属性
	printf("文件的大小:%ld\n",mystat.st_size);
	printf("文件的权限:%o\n",mystat.st_mode);
	//判断文件类型
	if(S_ISREG(mystat.st_mode))
	{
		printf("1.txt 普通文件\n");
	}
	if(S_ISDIR(mystat.st_mode))
	{
		printf("1.txt 目录文件\n");
	}
	//判断文件权限
	if((mystat.st_mode) & S_IRUSR)
	{
		printf("当前用户对于1.txt来说是可读的\n");
	}
	if((mystat.st_mode) & S_IWUSR)
	{
		printf("当前用户对于1.txt来说是可写的\n");
	}
	if((mystat.st_mode) & S_IXUSR)
	{
		printf("当前用户对于1.txt来说是可执行\n");
	}
	return 0;
}

 

 

  1.7文件的重定向
    命令重定向: ls -l> 1.txt  将标准输出重定向到1.txt
   
    linux系统将标准输入      标准输出      标准错误输出定义成了3个宏
                 0                1             2
             STDIN_FILENO  STDOUT_FILENO   STDERR_FILENO
    
    linux函数重定向:dup()和dup2()
    
    #include <unistd.h>

    int dup(int oldfd);//给文件描述符换一个新的数字
    返回值:成功  返回 新的文件描述符
            失败  返回 -1
    
    参数:int oldfd----》旧的文件描述符
    结论:新的文件描述符和旧的文件描述符都是指向同一个文件,都可以使用      
      
    int dup2(int oldfd, int newfd);
    返回值:成功  返回 新的文件描述符
            失败  返回 -1
    参数:int oldfd  旧的文件描述符
          int newfd  新的文件描述符

 总结一下: 1.txt---->fd
            2.txt---->fd1
            dup2(fd,fd1);//fd1跟2.txt已经无关了,跟1.txt有关系了

/*
    dup()
*/
#include "myhead.h"

int main(void)
{
	int fd;
	int newfd;
	//打开文件1.txt
	fd=open("1.txt",O_RDWR);
	if(fd == -1)
	{
		perror("open 1.txt fales\n");
		return -1;
	}
	printf("1.txt is %d\n",fd);
	//使用重定向函数,给1.txt重新分配新的文件描述符
	newfd=dup(fd);
	printf("newfd is %d\n",newfd);
	//往1.txt里面写内容
	write(fd,"hello",5);
	write(newfd,"world",5);
	return 0;
}
/*
    dup2()
*/
#include "myhead.h"

int main(void)
{
	int fd,fd1;
	int newfd;
	//打开文件1.txt
	fd=open("1.txt",O_RDWR);
	if(fd == -1)
	{
		perror("open 1.txt fales\n");
		return -1;
	}
	//打开文件2.txt
	fd1=open("2.txt",O_RDWR);
	if(fd == -1)
	{
		perror("open 2.txt fales\n");
		return -1;
	}
	printf("1.txt is %d\n",fd);
	//使用重定向函数,给1.txt重新分配新的文件描述符
	/* newfd=dup2(fd,15);
	dup2(fd,1); */
	dup2(fd,fd1);
	//printf("newfd is %d\n",newfd);
	//往1.txt里面写内容
	write(fd1,"hello",5);
	//write(newfd,"world",5);
	return 0;
}
/*
    dup2文件描述符改向
*/
#include "myhead.h"

int main(void)
{
	int fd,fd1;
	int newfd;
	//打开文件1.txt
	fd=open("1.txt",O_RDWR);
	if(fd == -1)
	{
		perror("open 1.txt fales\n");
		return -1;
	}
	//打开文件2.txt
	fd1=open("2.txt",O_RDWR);
	if(fd == -1)
	{
		perror("open 2.txt fales\n");
		return -1;
	}
	printf("1.txt is %d\n",fd);
	//使用重定向函数,给1.txt重新分配新的文件描述符
	newfd=dup2(fd,fd1);
	dup2(fd,fd1);//现在状态就表明两个文件描述符都会指向同一个地方,由前面fd决定
	printf("newfd is %d\n",newfd);
	//往1.txt里面写内容
	write(fd1,"hello",5);

	return 0;
}
/*
    dup2随便指定15为文件描述符
*/
#include "myhead.h"

int main(void)
{
	int fd;
	int newfd;
	//打开文件1.txt
	fd=open("1.txt",O_RDWR);
	if(fd == -1)
	{
		perror("open 1.txt fales\n");
		return -1;
	}
	printf("1.txt is %d\n",fd);
	//使用dup2重新分配新的文件描述符
	newfd=dup2(fd,15);//分配新的文件描述符15
	printf("newfd is %d\n",newfd);
	//往1.txt里面写内容
	write(newfd,"hello",5);//向15里面写入内容相当向1.txt里面写内容

	return 0;
}
  • (2)标准IO---->f开头一系列函数

          fopen()  fread() fwrite() fclose() fstat() fseek() ftell() rewind()
          fprintf() fscanf() sprintf() sscanf()  ferror() feof() 
          fputs() fgets() fputc()  fgetc() puts() gets() putchar() getchar()            
    
    1.文件的打开 fopen()
    头文件:#include <stdio.h>
    函数原型:
    FILE *fopen(const char *path, const char *mode);
    返回值: 成功  返回FILE * 类型的指针指向你要打开文件
             失败  返回NULL         
    
    函数参数:const char *path  ---->你要打开文件的位置 
              const char *mode  ----》文件权限
                        r     以只读的方式打开文件
                        r+    以可读可写的方式打开文件
                        w     以只写的方式打开文件,如果文件存在就清空,如果文件不存在就创建
                        w+    以可读可写的方式打开文件,如果文件存在就清空,如果文件不存在就创建
                        a     追加,如果文件不存在就新建 
                        a+    以读取和追加(文件末尾的写入),如果文件不存在,则创建它。

    2.文件的读写 fread() fwrite()
       头文件:#include <stdio.h>
       函数原型
       size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
       返回值: 成功 返回读取到完整的数据块的个数
                失败 返回0或者小于的数
                判断文件是否读完不要在用返回值判断,新方式feof()判断
       函数参数:void *ptr     ----》存储空间名
                 size_t size   ----》每一个数据块的大小 字节
                 size_t nmemb  ----》打算读取多少个数据块
                 FILE *stream  ----》文件类型的FELE *的文件指针
       
       size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);


    3.文件的关闭 fclose()
       头文件:#include <stdio.h>
       函数原型:
       int fclose(FILE *fp);
       返回值: 成功 返回0
                失败 返回feof()监测
        函数参数:FILE *fp  文件描述符

总结:
      (1)open那一组函数和fopen这一组函数之间区别
           区别一:open这一组, 对文件描述符进行操作
                   fopen这一组,对FILE *进行操作
           区别二:open这一组  不带缓冲区
                   fopen这一组 带缓冲区

                   
4.判断文件的结束标志  feof()
  头文件:#include <stdio.h>
  函数原型:
       int feof(FILE *stream);
       返回值: 不等于0  ---》文件读取完毕
                等于0    ---》文件没有读取完毕

#include "myhead.h"

int main()
{
	char buf[50];
	bzero(buf,50);
	//打开源文件
	FILE *filep1=fopen("1.txt","r+");
	if(filep1 == NULL)
	{
		perror("fopen filep1 false!\n");
		return -1;
	}
	//打开目标文件
	FILE *filep2=fopen("2.txt","w+");
	if(filep2 == NULL)
	{
		perror("fopen filep1 false!\n");
		return -1;
	}
	//拷贝
	while(1)
	{
		//读取源文件
		fread(buf,1,1,filep1);
		if(feof(filep1)!= 0)//表明文件读取完毕
		    break;
		fwrite(buf,1,1,filep2);
	}

    //关闭文件
    fclose(filep1);
    fclose(filep2);	
}


       
5.设置文件的读写偏移  man 3
  #include <stdio.h>

       int fseek(FILE *stream, long offset, int whence);
         返回值:成功 返回0
                 失败 返回-1  
                注意:lseek返回值和fseek()返回值意思不一样
         参数:FILE *stream  FILE * 文件
               long offset   偏移量
               int whence    偏移的位置
                    SEEK_SET  文件的开头
                    SEEK_CUR  当前的位置
                    SEEK_END  文件的末尾   
            例子:fseek(filep1,0,SEEK_SET);
       long ftell(FILE *stream);
         返回值:成功 返回文件当前位置距离文件开头的字节数
                 失败 返回-1
            例子:long ftell(filep1);相当于fseek(filep1,0,SEEK_END);
         
       void rewind(FILE *stream);//没有返回值
            例子:void rewind(filp1)//等价于fseek(filep1,0,SEEK_SET)
              将文件的偏移设置为起始位置
    
6.获取文件属性  fstat()
    头文件:#include <sys/stat.h>

       int fstat(int fildes, struct stat *buf);
       返回值:成功  返回0
               失败  返回-1
        参数:int fildes       你要获取属性的那个文件的文件描述符
              struct stat *buf 存放你获取到的文件属性 
7.fprintf() fscanf() sprintf() sscanf()
 标准输入      stdin
 标准输出      stdout
 标准错误输出  stderr
      可变参的函数(变参函数)
 #include <stdio.h>
       7.1 int fprintf(FILE *stream, const char *format, ...);
           参数:FILE *stream        FILE *  文件名
                 const char *format  字符串
                 ...
            例子:fprintf(filep,"hello%s%d%.2f\n",buf,year,d);
               //文件内容拼接

/*
    fprintf()的使用
*/
#include "myhead.h"

int main()
{
	char buf[]="world";
	int year=2018;
	float d=5.20;
	FILE *filep=fopen("1.txt","w+");
	if(filep == NULL)
	{
		perror("filep false\n");
		return -1;
	}
	fprintf(filep,"hello%s%d%.2f\n",buf,year,d);//拼接
	fprintf(stdout,"%s\n",buf);//证明可以通过标准输出把内容显示到屏幕上
	//等同于printf("%s\n",buf);
}


                            
       7.2 int sprintf(char *str, const char *format, ...);
           //按照你指定的格式拼接字符串,比strcat要厉害
           参数:char *str           字符串拼接指定位置
                 const char *format  字符串格式
                 ... 
            例子:sprintf(buf0,"%sworld-%d-%d-%d",buf,year,month,day);

#include "myhead.h"

int main()
{
	char buf0[100];
	char buf[]="hello";
	int year=2018;
	int month=7;
	int day=8;
	float a=12.5;
	sprintf(buf0,"%sworld-%d-%d-%d",buf,year,month,day);
	printf("%s\n",buf0);
	return 0;
}


            
       7.3  int fscanf(FILE *stream, const char *format, ...);
            参数:FILE *stream        FILE *  文件名
                  const char *format  字符串
                  ...
            往文件里面添加内容

#include "myhead.h"

int main()
{
	char buf[100];
	bzero(buf,100);
	FILE *filep=fopen("1.txt","r+");
	if(filep == NULL)
	{
		perror("filep false\n");
		return -1;
	} 
	fscanf(stdin,"%s",buf);
	fprintf(stdout,"%s",buf);
	return 0;
}


       
       7.4 int sscanf(const char *str, const char *format, ...);
            //按照你指定的格式拆分字符串
            参数:char *str           字符串拆分指定位置
                 const char *format   字符串格式
                 ... 
            例子:sscanf(time,"%d-%d-%d",&year,&month,&day);//访问的是地址 &

#include "myhead.h"

int main()
{
	char time[]="2018-12-1 16:00:30 MON";
	int year,month,day;
	sscanf(time,"%d-%d-%d",&year,&month,&day);//访问的是地址 &
	printf("year %d month %d day %d\n",year,month,day);
	return 0;
}

8.fputs() fgets() fputc()  fgetc() puts() gets() putchar() getchar()    
   #include <stdio.h>

   int fgetc(FILE *stream);//从文件中读取一个字符 fread(buf,1,1,stream);
           返回值:你读取到的那个字符的ASCII码
   int getc(FILE *stream);//从文件当中读取一个字符
           返回值:你读取到的那个字符的ASCII码
   char *fgets(char *s, int size, FILE *stream);
         //从文件读取size个字节的数据放到指针s中
         返回值:返回读到的字符串的首地址  指针
          fgets(buf,100,stdin);//获取键盘输入
   int getchar(void);
         //监测缓冲区的回车字符
         while(getchar()!='\n')         
   char *gets(char *s);  gets(buf);
         //默认获取键盘输入的字符串

 #include <stdio.h>

   int fputc(int c, FILE *stream);//往文件中写入一个字符  fwrite
   
   int putc(int c, FILE *stream);//往文件中写入一个字符  fwrite

   int fputs(const char *s, FILE *stream);//相当于打印
            fputs(buf,stdout);
   int putchar(int c);  //打印字符
            putchar(a)==putchar(97)
   int puts(const char *s);//打印字符串  puts(buf);

/*
   使用fputs和fgets实现文件拷贝 
*/
#include "myhead.h"

int main(void)
{
	int ret;
	char buf[100];
	
	//打开源文件
    FILE *myfile1=fopen("1.txt","r+");
    if(myfile1 == NULL)
	{
		fputs("myfile create failed!\n",stdout);
		return -1;
	}
	//打开文件拷贝的位置
	FILE *myfile2=fopen("2.txt","w+");
    if(myfile2 == NULL)
	{
		fputs("myfile create failed!\n",stdout);
		return -1;
	}
	//拷贝
	while(1)
	{
		bzero(buf,100);
	    //读取文件里面的内容
		fgets(buf,100,myfile1);
		if(feof(myfile1)!=0)
			break;
		//写数据到文件
	    fputs(buf,myfile2);
	}
	//关闭文件
	fclose(myfile1);
	fclose(myfile2);
	return 0;
}


 

  • 目录操作

1.相关的接口函数
      1.1目录的打开  opendir()
       头文件#include <sys/types.h>
             #include <dirent.h>
       函数原型:
       DIR *opendir(const char *name);
       返回值:成功 返回DIR类型的指针指向你打开的目录
               失败 返回NULL
               
            参数:const char *name 完整的目录路径   
    
      1.2 目录的读取 readdir()
       #include <dirent.h>

       struct dirent *readdir(DIR *dirp);
              返回值:struct dirent 目录结构体指针
              
        struct dirent {
               ino_t          d_ino;       /* 节点编号*/
               off_t          d_off;       /* 目录的下一个偏移位置 */
               unsigned short d_reclen;    /* 目录大小*/
               unsigned char  d_type;      /* 目录类型*/
               char           d_name[256]; /* 目录名字 */
           };//存放的是目录当中的每个文件的相关信息
    文件类型判断
       DT_BLK      This is a block device. //块设备文件

       DT_CHR      This is a character device.//字符设备文件

       DT_DIR      This is a directory.//目录文件

       DT_FIFO     This is a named pipe (FIFO).//管道文件

       DT_LNK      This is a symbolic link.//软连接文件

       DT_REG      This is a regular file.//普通问价

       DT_SOCK     This is a UNIX domain socket.//套接字文件
       
       DT_UNKNOWN  The file type is unknown.//不认识类型
    
      1.3新建目录 mkdir
        #include <sys/stat.h>
       函数原型:
       int mkdir(const char *path, mode_t mode);
        参数:const char *path  ----》你要建立的目录的路径
                  mode_t mode      ----》新建文件的权限 0777
               
      1.4关闭目录 closedir()
        #include <sys/types.h>

       #include <dirent.h>

       int closedir(DIR *dirp);//结构体指针
      
     以树形方式去查看目录中的内容  tree  目录名
      总结:就是学习使用一些系统提供的接口函数
       系统IO --->标准IO--->目录操作

//mytree实现 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
void mytree(const char *path)
{
	int i;
	static int flag=0;
	char dirpath[1024];
	struct dirent *mydirent;
	DIR *mydir=opendir(path);
	if(mydir==NULL)
	{
		perror("opendir false!\n");
		exit(1);
	}
	while((mydirent = readdir(mydir)) != NULL)
    {
		if(!strcmp(mydirent->d_name,".")||!strcmp(mydirent->d_name,".."))
			continue;

        for(i = 0; i < flag; i++)
        {
            printf("|");
            printf("     ");
        }
        printf("|___ ");
        printf("%s\n", mydirent->d_name);
		if(mydirent->d_type == DT_DIR)
        {
			sprintf(dirpath,"%s/%s",path,mydirent->d_name);
			flag++;
			mytree(dirpath);
			flag--;//因为调用的时候又运行一次falg++
		}
	}
	closedir(mydir);
}
int main(int argc , char *argv[])
{
	printf("%s\n",argv[1]);
	mytree(argv[1]);
	return 0;
}

     
      
      

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jason~shen

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值