温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Linux 标准I/O库常用函数总结

发布时间:2020-06-14 14:07:39 来源:网络 阅读:415 作者:昵称真难改 栏目:系统运维

    上一篇总结了文件I/O的系统调用,今天来总结下标准I/O库在工作几年经常使用的函数。

    标准I/O库(#include<stdio.h>)实际就是封装了系统调用;这样做的主要目的是减少对系统调用的调用,从而提高效率。

1、流和FILE对象

文件I/O操作的的文件描述符,而标准I/O库操作的是流即就是FILE对象。当打开一个流时,返回一个FILE对象。

2、标准输入、标准输出、标准错误

对应文件I/O的文件描述符文件为:0STDIN_FILENO)、1STDOUT_FILENO)、2STDERR_FILENO

对应标准I/O库的流为:stdinstdoutstderr

3、标准I/O提供三种缓冲(减少对系统调用的调用)

    int setbuf(FILE *stream,char *buf );/*buf =null 关闭缓冲,buf长度=BUFSIZE设置缓冲区*/
    int setvbuf(FILE *stream,char *buf,int mode,size_t size);/*mode :_IOFBF 全缓冲;_IOLBF行缓冲;_IONBF不带缓冲。长度为size 的buf,如果buf=NULL,则为系统默认大小。*/
    int fflush(FILE*fp);/*强制刷新一个流,用于刷新缓冲区*/

1)  全缓冲:当不涉及到交互式设备时,则为全缓冲。

2)  行缓冲:终端设备一般是行缓冲。有时不需要缓冲区,比如之前例子里,需要实时打印printf,所以要讲其设置成不带缓冲: 

      setvbuf(stdout,NULL,_IONBF,0)

3)  不带缓冲:标准出错就是不带缓冲,当出现错误的时候会立即输出。

4、 打开和关闭流

    FILE *fopen(const char *path,const char *mode);
    FILE *fdopen(int fd,const char *mode);
    FILE *freopen(const char *path,const char *mode,FILE *stream);

三个函数都是打开一个流,fopen:打开一个指定的流;fdopen:流和一个文件描述符结合;freopen:在一个指定的流上打开一个指定的文件,已打开则关闭、已定向则消除。

mode:r读、r+读写、w写、w+读写、a在文件尾部写、a+在文件尾部读和写。

int fclose(FILE *stream);/*关闭一个流*/

5、读和写流

读和写流分为三种:每次一个字符的I/O;每次一行的I/O;直接I/O(二进制I/O)按字节操作。

1)  字符I/O

读函数:

    int getc(FILE *fp);
    int fgetc(FILE *fp);
    int getchar(void);/*getc(stdin)*/

因为要判断出错或者是不是到了流的末端(EOF = -1),所以返回值都是整型。

用函数:int ferror(FILE *fP)/*未出错返回0*//int feof(FILE *fp)/*返回0表示文件未结束*/

写函数:

    int putc(int c,FILE *fp);
    int fputc(int c,FILE *fp);
    int putchar(int c);/*putc(c,stdout)*/

2)  I/O

读函数:

    char *fgets(char *buf,int n,FILE *fp);/*读到下一个换行符如果buf够大,如果buf没有一行大,返回一个不完整的行,下次继续读改行*/
    char *gets(char *buf);/*从stdin读*/

       写函数:

    char fputs(char *buf,FILE *fp);
    char puts(char *buf);/*写到stdout*/

3)  二进制I/O

    size_t fread(void *ptr,size_t size,size_t nmemb,FILE *stream );
    size_t fwite(const void*ptr,size_t size,size_t nmemb,FILE *stream);

/*size指定ptr长度,nmemb指定读或者写几个size长度的ptr*/

工作中经常从flash读出设备的镜像:

/*read boot & image*/
cs_status cs_build_image()
{
    cs_uint32 offset = 0;
    int ret = 0;
    FILE *  bootfp = NULL;
    FILE *  imgfp = NULL;
    ULONG   lByte = 0;                  /*读取文件时的单元长度*/
    UCHAR   ucBuffer[1024] = {0};/*用来存储读出来镜像单元*/
    ULONG   ulImageLen = 0;                    /*记录文件的总体长度*/
    UCHAR   uc8124imgName[48] = {0};          /*local file name*/
    UCHAR   uc8124stage2ImgName[48] = {0};          /*local file name*/
    UCHAR   head = 64;
    sprintf( uc8124stage2ImgName, "/ram0/%s", "stage2" );
    if( NULL == ( bootfp = fopen( uc8124stage2ImgName, "wb+" ) ) )
    {
        printf( "open to  cs8124_img file!\r\n" );
        return ERROR;
    }
    ret = GenHwSysFlashload8124Stage2Image(bootfp);
    if( OK != ret )
    {
        printf( "read 8124Stage2Image from flash error! \r\n" );
        return ERROR;
    }

    g_uc8124stage2Image = (cs_uint8*)malloc(sizeof(cs_uint8) * TEST_MAX_OLT_LOADER_IMAGE );
    if(g_uc8124stage2Image == NULL){
        printf("malloc g_uc8124stage2Image error\n");
    }
    memset(g_uc8124stage2Image, 0, TEST_MAX_OLT_LOADER_IMAGE);
    fseek( bootfp, 0, SEEK_SET );
    while( 0 < ( lByte = fread( ucBuffer, 1, 1024, bootfp ) ) )
    {
		ulImageLen += (lByte-head);
		/*写在本地文件操作*/
        memcpy( g_uc8124stage2Image + offset, ucBuffer+head , lByte-head );
		offset += lByte-head;
		memset( ucBuffer, 0 , sizeof( ucBuffer ) );
		head = 0;
    }
    printf("[%s%d ] g_uc8124stage2Image:%d\n",__FILE__,__LINE__,ulImageLen);
    g_ucStage2ImageLen = ulImageLen;
    if(TEST_MAX_OLT_LOADER_IMAGE < ulImageLen){
        return ERROR;
    }
    fclose( bootfp);
    ret = remove( uc8124stage2ImgName );
    if( OK != ret  )
    {
        printf( " 8124stage2Image error! \r\n" );
        return ERROR;
    }	
	/*get cs8124 image(firmware)*/
	
    sprintf( uc8124imgName, "/ram0/%s", "imgenew" );
    if( NULL == ( imgfp = fopen( uc8124imgName, "wb+" ) ) )
    {
	printf( "Fail to create cs8124_img file!\r\n" );
	return ERROR;
    }
    ret = GenHwSysFlashload8124Image(imgfp);
    if( OK != ret )
    {
	printf( "read 8124Image from flash error! \r\n" );
	return ERROR;
    }
    g_ucpOltImage = (cs_uint8*)malloc(sizeof(cs_uint8) * TEST_MAX_OLT_IMAGE );
    if(g_ucpOltImage == NULL){
    printf("malloc g_ucpOltImage error\n");
    }
    memset(g_ucpOltImage, 0, TEST_MAX_OLT_IMAGE);
    fseek( imgfp, 0, SEEK_SET );
    lByte = 0;
    ulImageLen = 0;
    offset = 0;
    head = 64;
    memset( ucBuffer, 0 , sizeof( ucBuffer ) );
    while( 0 < ( lByte = fread( ucBuffer, 1, 1024, imgfp ) ) )
    {
	ulImageLen += (lByte-head);
	/*写在本地文件操作*/
	memcpy( g_ucpOltImage + offset, ucBuffer+head , lByte-head );
	offset += lByte-head;
	memset( ucBuffer, 0 , sizeof( ucBuffer ) );
	head = 0;
    }
    printf("[%s%d ] g_ucpOltImage len:%d\n",__FILE__,__LINE__,ulImageLen);
    g_ucOltImageLen = ulImageLen;
    if(TEST_MAX_OLT_IMAGE < ulImageLen){
     	return ERROR;
    }
    fclose( imgfp);
    ret = remove( uc8124imgName );
    if( OK != ret )
    {
	printf( " uc8124imgName error! \r\n" );
	return ERROR;
    }	 
}

6、 定位流函数

int fseek(FILE *fp,long offset,int whence);/*和文件I/Olseek函数类似,whence相同:SEEK_SET从文件起始开始,SEEK_CUR从文件当前开始,SEEK_END从文件末端开始*/

7、  格式化I/O

格式化输出函数:

    int printf(const char *format,….);
    int fprintf(FILE *fp,const char *format,….);
    int sprintf(char *buf,const char *format,…);
    int snprintf(char *buf,size_t n,const char *format,…);

/*printf将格式化数据写到标准输出,fprintf写到指定的流,sprintf将格式化的字符串送到数组buf中。snprintf指定buf长度n*/

在工作中经常使用snprintf,比如刚刚开发完静态路由是用到的:

格式化输入函数(和输出类似):

    int scanf(const *format,…);
    int fscanf(FILE *fp,const *format,..);
    int sscanf(const char *buf,const char *format,…);

8、创建临时文件函数

    FILE *tmpfile(void);/*创建一个临时二进制文件wb+,在关闭该文件或程序结束时将自动删除这种文件*/


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI