溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-06-14 14:07:39 來源:網絡 閱讀:439 作者:昵稱真難改 欄目:系統運維

? ? 上一篇總結了文件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庫的流為:stdin、stdout、stderr;

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

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女