• Linux 标准IO


    应用层

    一、介绍

    1.标准IO库的所有操作都是围绕流(strem)来实现的;
    FILE * 流指针,文件指针
    2./dev 目录下

    stderr  2 //标准出错文件
    stdout  1 //标准输出文件
    stdin   0 //标准输入文件
    
    • 1
    • 2
    • 3

    二、库函数使用

    1.printf() 家族,调用 stdio.h头文件

    stdio.h

    #include 
    
           int printf(const char *format, ...);
           int fprintf(FILE *stream, const char *format, ...);//把字符输出到流
    			例如:
    			fprintf(stdout,"hello world\n");
    			fprintf(stderr,"hello world\n"):
    			fprintf(stdout,"a=%d\n",a);//带参数
    			
           int dprintf(int fd, const char *format, ...);
           int sprintf(char *str, const char *format, ...);//向字符串中写入,
           		例:
           		sprintf(buf,"hello world  %f\n",3.14);
           
           int snprintf(char *str, size_t size, const char *format, ...);
    
           #include 
    
           int vprintf(const char *format, va_list ap);
           int vfprintf(FILE *stream, const char *format, va_list ap);
           int vdprintf(int fd, const char *format, va_list ap);
           int vsprintf(char *str, const char *format, va_list ap);
           int vsnprintf(char *str, size_t size, const char *format, va_list ap);
    
    //返回值
    成功返回后,这些函数返回打印的字符数(不包括用于结束输出到字符串的空字节)。
    输出错误,则返回负值
    
    • 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

    2.fclose();关闭流,可以是标准输入输出、出错流,也可以是打开的文件流

       int fclose(FILE *stream);
    //返回值
    RETURN VALUE
           Upon  successful  completion  0 is returned.  Otherwise, EOF is returned and errno is
           set to indicate the error.  In either case any further access (including another call
           to fclose()) to the stream results in undefined behavior.
           成功完成后返回O。否则,将返回EOF并设置errno以指示错误。在这两种情况下,对流的任何进一步访问(包括对fclose()的另一个调用)都会导致未定义的行为。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    关闭输出流,则无法输出

    fclose(stdout);
    fprintf(stdout,"hello world\n");//
    
    • 1
    • 2

    2.标准IO 中的缓冲机制

    scanf();函数在缓冲区读取字符,当输入字符最后一个回车键(\n)没有输入,依然保存在缓冲区,需要使用getchar();取走回车键的字符,不然会在下一次输入时,上次留下的回车键读入。
    解决这个问题,在多个scanf()函数中间添加getchar();

    (1)在内存空间中预留了一定的存储空间,这用来缓冲输入或输出的数据。

    FILE *fp=stdin;//大小为1024字节
    
    char a=getchar();//需要设置输入
    fp->IO_buf_end //输入缓冲区尾部指针
    fp->IO_buf_base //输入患处区头部指针
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (2)缓冲区的分类
    1)全缓存[4096字节],输入输出是对文件操作;

    ./a.out >log.txt//当输出的字符少于4096时,无法输出,大于该值则输出
    
    • 1

    2)行缓存【1024字节】,输入输出是对屏幕操作;
    特点:
    遇到\n会刷新,缓冲满了会刷新,程序正常结束会刷新【调用exit或从main函数返回】
    调用fflush()会强制刷新缓存;遇到\n会刷新缓存。

    main()
    {
    	for(i=1;i<=200;i++)
    	{
    		printf("A");
    	}
    	while(1);
    }
    //执行该程序,未能在输出栏看到输出数据,以为输出的内容在缓冲区,并且未达到刷新缓冲区的要求,所以看不到,当设置i<1024时就可以输出,或者最后输出地方添加\n,fflush()函数。
    fflush(stdout);
    或者使用 putchuar('\n');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3. int main(int argc,const char *argc[])函数参数

    int main(int argc,const char * argv[])
    {
    
    }
    argc :输入参数的个数
    argv[]: 输入参数的数组
    		argv[0]  :执行文件的名字
    		argv[1]  :执行文件 后第一参数
    		
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4. fopen()函数,打开文件,返回一个文件指针

    FILE *fopen(const char *path,const char *mode);
    //返回值为一个文件指针,
    	返回NULL则表示打开出错
    //const char *path  文件地址,是一个字符串
    //const char *mode  打开文件的方式
    		打开文件方式
    		"r"  :只读打开,不能修改文件
    		"r+" :读写方式打开,没有文件报错
    		"w"  :只写打开,没有文件创造文件,有内容则清空重写
    		"w+" :读写打开,没有文件创造文件,有内容则清空重写;
    		"a"  :追加方式打开,没有文件创造文件;
    		"a+" :追加读写方式打开,没有文件创造文件,读从文件开头开始读,写从文件结尾的位置写
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    5. errno 错误码

    vim -t EIO //查看错误码
    errno //全局错误码使用errno.h 
    man 3 perror
    打印错误码
    printf("%d",errno);
    
    perror("Fail to open");自动把系统错误打印在后面
    自动添加  :错误信息
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5.strerror();//返回值是错误信息的字符串

    打印错误信息
    printf("%s",strerror(errno));//函数内传入错误码,打印错误信息
    
    • 1
    • 2

    使用标准IO把字符写入文件(1)

    #include
    #include
    #include
    
    int main(int argc,const char* argv[])
    {
    	FILE *fp=NULL;
    	if(artc!=2)
    	{
    		fprintf(stderr,"usage: %s log.txt\n",argv[0]);//如果没有给文件名,则报错
    		return -1;
    	}
    	//读写打开
    	fp=fopen(argv[1],"r+);
    	if(NULL==fp)
    	{
    		fprintf(stderr,"Fail to fopen %s\n",strerror(errno));
    		return -1;
    	}
    	fprintf(fp,"hello world!\n");//把字符串写入文件指针中
    	
    	//关闭文件
    	fclose(fp);
    	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

    6.fputc(FILE *stream); //单字符输入输出

     #include 
    
           int fputc(int c, FILE *stream);
    
           int fputs(const char *s, FILE *stream);
    
           int putc(int c, FILE *stream);
    
           int putchar(int c);
    
           int puts(const char *s);
           
    
    int fgetc(FILE *stream);//从流读出字符
    
           char *fgets(char *s, int size, FILE *stream);
    
           int getc(FILE *stream);
    
           int getchar(void);
    
           int ungetc(int c, FILE *stream);
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    读取文件,把文件内容打印在终端。(类似cat命令)

    #include
    
    int main(int argc,const char * argv[])
    {
    	FILE *fp=NULL;
    	int ch;
    	if(artc!=2)
    	{
    		fprintf(stderr,"usage: %s log.txt\n",argv[0]);//如果没有给文件名,则报错
    		return -1;
    	}
    	//读写打开
    	fp=fopen(argv[1],"r+");
    	if(NULL==fp)
    	{
    		fprintf(stderr,"Fail to fopen %s\n",strerror(errno));
    		return -1;
    	}
    	
    	while(1)
    	{
    		ch=fgetc(fp);
    		if(ch==EOF)
    		{
    			break;
    		}
    		fputc(ch,stdout);
    	}
    	fclose(fp);
    	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

    7.char *fgets(char *s, int size, FILE *stream);//最多获取字符数比size少一个,最后要加一个\0 //按行读取

    从流中读取size-1个字符,写入指针s所指地址,在EOF 或者换行符后停止读取,如果读取了换行符,则将其存储到缓冲区。
    返回值:成功返回s的地址,失败或者读到文件末尾返回NULL;

      #include 
    
           int fgetc(FILE *stream);
    
           char *fgets(char *s, int size, FILE *stream);//最多获取字符数比size少一个,最后要加一个\0
    
           int getc(FILE *stream);
    
           int getchar(void);
    
           int ungetc(int c, FILE *stream);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    8. int fputs(const char *s, FILE *stream); //把字符串输入流中,遇到’\0’就结束。

      #include 
    
           int fputc(int c, FILE *stream);
    
           int fputs(const char *s, FILE *stream);
    
           int putc(int c, FILE *stream);
    
           int putchar(int c);
    
           int puts(const char *s);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    //示例:向文件中输入

    FILE *fp=NULL;
    char buf{100]={0};
    
    fp=fopen("log.txt","w");
    if(fp==NULL)
    {
    	perror("Fail to fopen!");
    	return -1
    }
    strcpy(buf,"hello world");
    
    int ret=fputs(buf,fp);
    if(ret<0)//EOF=-1
    {
    	perror("Fail to fputs");
    	return -1;
    }
    close(fp);
    
    //return value:返回值
    
    		//fputc(), putc() and putchar() return the character written as an unsigned char cast to an int or EOF on error. EOF 在 /usr/include/stdio.h  宏定义为-1
    		
    
        //   puts() and fputs() return a nonnegative number on success, or EOF on error.
    
    
    • 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

    在这里插入图片描述
    //示例:当输入 quit 时退出

    #include
    #include
    #include
    
    int main(int argc,const char *argv[])
    {
    	char buf[120]={0}while(1)
    	{
    		bzero(buf,sizeof(buf));
    		putchar('>');
    		fgets(buf,sizeof(buf),stdin);
    		if(strncmp(buf,"quit",4)==0)
    		{
    			break;
    		}
    		fputs(buf,stdout);
    		
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    9.统计行数 命令行【 wc -l 文件名 获得文件的行数,-w 单词个数 -c 大小 】

    //

    #include
    
    int getLine(FILE *fp)
    {
    	char buf[1024]={0};
    	int line=0;
    	while(fgets(buf,sizeof(buf),fp)!=NULL)//当没有读到文件尾部的时候,继续读
    	{
    		if(buf[strlen(buf)-1]=='\n')
    		{
    			line++; 
    		}
    		memset(buf,0,sizeof(buf));
    		
    	}
    	return line;
    }
    int main(int argc,const char *argv[])
    {
    	FILE *fp;
    	int line=0;
    	if(argc!=2)
    	{
    		perror(stderr,"Usage: %s log.txt",argv[0]);
    		return -1;
    	}
    	fp=fopen(argv[1],"r");
    	if(NULL==fp)
    	{
    		perror("Fail to fopen");
    		return -1;
    	}
    	line=getLine(fp);
    	printf("%s:%d\n",argv[1],line);
    	fclose();
    	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

    10. size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);//从文件流指针读,写入ptr指向的数据缓冲区

    size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);从ptr指向的缓冲区写入文件流指针。

    //返回值:成功返回读取的个数

    //示例:把结构体写入文件[od -c 文件名 //可以查看文件的结构]

    #include
    
    struct student
    {
    	char name[20];
    	int id;
    	int score;
    };
    int main(int argc,const char *argv[])
    {
    	FILE *fp;
    	struct student stu={"jack",1,100);//给结构体赋值
    	
    	if(argc!=2)
    	{
    		perror(stderr,"Usage: %s log.txt",argv[0]);
    		return -1;
    	}
    	fp=fopen(argv[1],"w");
    	if(fp==NULL)
    	{
    		perror("Fail to fopen");
    		return -1;
    	}
    	fwrite(&stu,sizeof(stu),1,fp);//1是写入数据的个数
    	fclose(fp);
    	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

    11. int fseek(FILE *stream, long offset, int whence);//定位读文件光标的位置

    //参数:whence 光标相对偏移起点:SEEK_SET 以文件开头为起点;SEEK_CUR 当前位置为偏移起点;SEEK_END 文件结尾为偏移起点;
    //参数:offset >0 则向后偏移,<0 向前偏移
    //返回值:成功返回0,失败返回-1,置errno

     #include 
    
           int fseek(FILE *stream, long offset, int whence);
    
           long ftell(FILE *stream);//返回当前光标的位置
    
           void rewind(FILE *stream);//将光标定位到文件开头
    
           int fgetpos(FILE *stream, fpos_t *pos);
           int fsetpos(FILE *stream, const fpos_t *pos);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    //示例:移动文件光标//文件开头为0

    fseek(fp,4,SEEK_SET);//定位到文件开头往后数4bytes的位置
    fseek(fp,-4,SEEK_END);//定位到文件末尾往前数4bytes的位置
    fseek(fp,10,SEEK_END);//将文件的大小扩充10bytes
    
    • 1
    • 2
    • 3

    把光标定位到开头

    fseek(fp,0,SEEK_SET);//和rewind 等价
    rewind(fp);//该函数和上个函数等价
    
    • 1
    • 2
  • 相关阅读:
    Lens5 指南:专为Kubernetes人员设计的IDE
    Windows10下Tomcat8.5安装教程
    C++前缀和算法的应用:从仓库到码头运输箱子原理、源码、测试用例
    java-php-net-python-基于的相册软件的设计与实现计算机毕业设计程序
    JTS:03 创建Geometry对象
    1.SpringMVC入门案例
    9.数值统计
    c/c++常见的数据类型表示的范围
    【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
    codeforces:Codeforces Round #821 (Div. 2) 【思维 + 贪心分贡献的dp】
  • 原文地址:https://blog.csdn.net/jun8086/article/details/127703015