Linux 標準I/O庫經常使用函數總結

    上一篇總結了文件I/O的系統調用,今天來總結下標準I/O庫在工做幾年常常使用的函數。數組

    標準I/O庫(#include<stdio.h>)實際就是封裝了系統調用;這樣作的主要目的是減小對系統調用的調用,從而提升效率。ide

一、流和FILE對象函數

文件I/O操做的的文件描述符,而標準I/O庫操做的是流即就是FILE對象。當打開一個流時,返回一個FILE對象。ui

二、標準輸入、標準輸出、標準錯誤spa

對應文件I/O的文件描述符文件爲:0STDIN_FILENO)、1STDOUT_FILENO)、2STDERR_FILENOorm

對應標準I/O庫的流爲:stdinstdoutstderr對象

三、標準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,因此要講其設置成不帶緩衝: rem

      setvbuf(stdout,NULL,_IONBF,0)

3)  不帶緩衝:標準出錯就是不帶緩衝,當出現錯誤的時候會當即輸出。

四、 打開和關閉流

    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);/*關閉一個流*/

五、讀和寫流

讀和寫流分爲三種:每次一個字符的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;
    }	 
}

六、 定位流函數

int fseek(FILE *fp,long offset,int whence);/*和文件I/Olseek函數相似,whence相同:SEEK_SET從文件起始開始,SEEK_CUR從文件當前開始,SEEK_END從文件末端開始*/

七、  格式化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,…);

八、建立臨時文件函數

    FILE *tmpfile(void);/*建立一個臨時二進制文件wb+,在關閉該文件或程序結束時將自動刪除這種文件*/
相關文章
相關標籤/搜索