最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言由淺入深講解文件的操作下篇

 更新時(shí)間:2022年04月01日 12:08:36   作者:_奇奇  
C語(yǔ)言具有操作文件的能力,比如打開(kāi)文件、讀取和追加數(shù)據(jù)、插入和刪除數(shù)據(jù)、關(guān)閉文件、刪除文件等。與其他編程語(yǔ)言相比,C語(yǔ)言文件操作的接口相當(dāng)簡(jiǎn)單和易學(xué)

第一篇講了文件的基本概念,和文件如何打開(kāi)和關(guān)閉。第二篇主要介紹文件的順序讀寫(xiě)和隨機(jī)讀寫(xiě)。外加文件緩沖區(qū)的知識(shí)點(diǎn)。

文件的順序讀寫(xiě)

字符輸入輸出fgetc和fputc

fgetc

fgetc:字符輸入函數(shù),也就是讀文件時(shí)用的函數(shù)。

函數(shù)功能:Read a character from a stream

從一個(gè)文件中讀一個(gè)字符到內(nèi)存中。

函數(shù)原型:

int fgetc( FILE *stream );

參數(shù)為stream,也就是文件指針。

返回值:fgetc return the character read as an int or return EOF to indicate an error or end of file.該函數(shù)調(diào)用成功會(huì)返回讀取到的的字符的ASCIIC碼值;若讀取文件時(shí)發(fā)生錯(cuò)誤,或是已經(jīng)讀取到文件末尾,則返回EOF。

舉例:將data.txt文件中的內(nèi)容讀取,并打印。

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	//打開(kāi)文件
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 0;//文件打開(kāi)失敗,失敗返回
	}
	//對(duì)文件進(jìn)行輸入字符操作
	int ch = 0;
	while ((ch = fgetc(pf))!= EOF)
	{
		printf("%c", ch);
	}
	//關(guān)閉文件
	fclose(pf);
	pf = NULL;
	return 0;
}

fputc:

函數(shù)功能:從內(nèi)存中寫(xiě)一個(gè)字符到文件中。也就是輸出字符。

函數(shù)原型:

int fputc( int c, FILE *stream );

第一個(gè)參數(shù)為待輸出的字符,第二個(gè)參數(shù)是文件指針。

返回值:Each of these functions returns the character written. For fputc , a return value of EOF indicates an error.

如果正常運(yùn)行則返回此字符,如果返回EOF則意味著失敗。

舉例:將字母a~z寫(xiě)入到data.txt文件中

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	//打開(kāi)文件
	FILE* pf = fopen("data.txt", "w");
	//文件打開(kāi)失敗,失敗返回
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 0;
	}
	//對(duì)文件進(jìn)行輸出字符的操作
	char i = 0;
	for (i = 'a'; i <= 'z'; i++)
	{
		fputc(i, pf);
	}
	//關(guān)閉文件
	fclose(pf);
	pf = NULL;
	return 0;
}

文本行輸入輸出函數(shù)fgets和fputs

fgets和fputs是對(duì)文本行的操作,相當(dāng)于對(duì)字符串的操作。這是不同于fgetc和fputc的地方。

fgets:

函數(shù)功能:從文件中讀一行字符到內(nèi)存中,也就是輸入。

函數(shù)原型:

char *fgets( char *string, int n, FILE *stream );

第一個(gè)參數(shù)是指向文件字符串的指針,第二個(gè)參數(shù)是讀幾個(gè)字符的意思,第三個(gè)參數(shù)是指向文件的指針。

返回值:Each of these functions returns string. NULL is returned to indicate an error or an end-of-file condition. Use feof or ferror to determine whether an error occurred.每一個(gè)這樣的函數(shù)結(jié)束后正常情況返回一個(gè)指向這個(gè)字符串的字符指針。如果返回NULL則意味著遇到錯(cuò)誤,或者是文件結(jié)束。但是重點(diǎn)來(lái)了~,想要判斷到底是錯(cuò)誤導(dǎo)致的返回,還是文件結(jié)束導(dǎo)致的返回,還需要使用feof函數(shù)和ferror函數(shù)來(lái)判斷。

下面有涉及feof函數(shù)的用法

舉個(gè)例子。

   //feof是用來(lái)在結(jié)束后判斷是什么原因結(jié)束的
    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp))
        puts("End of file reached successfully");
    fclose(fp);
}

注意:

1.在fgets函數(shù)讀取到指定字符數(shù)之前,若讀取到換行符(’\n’),則停止讀取,讀取帶回的字符包含換行符。

2. fgets函數(shù)讀取到第n-1個(gè)字符時(shí)都沒(méi)有遇到換行符(’\n’)時(shí),則返回讀到的前n-1個(gè)字符,并在末尾加上一個(gè)NULL字符返回。這樣加起來(lái)共n個(gè)字符

fputs:

函數(shù)功能:寫(xiě)一行字符串到文件中,也就是輸出。

函數(shù)原型:

int fputs( const char *string, FILE *stream );

第一個(gè)參數(shù)為指向內(nèi)存中這個(gè)字符串的指針,第二個(gè)參數(shù)為指向這個(gè)文件的文件指針。返回值:該函數(shù)調(diào)用成功會(huì)返回一個(gè)非負(fù)值;若輸出時(shí)發(fā)生錯(cuò)誤,則返回EOF。

格式化輸入輸出函數(shù)fscanf和fprintf

fscanf和fprintf也叫格式化輸入(讀)和輸出(寫(xiě))函數(shù)。

fscanf:

函數(shù)功能:按照一定的格式如%s,%c,從指定文件的位置輸入到內(nèi)存中。

函數(shù)原型:

int fscanf( FILE *stream, const char *format [, argument ]... );

fscanf函數(shù)的第一個(gè)參數(shù)是讀取數(shù)據(jù)的位置也就是文件指針,第二個(gè)參數(shù)也就是scanf函數(shù)的參數(shù),也就是取地址。

除了第一個(gè)參數(shù)是需要指針位置其余和scanf函數(shù)操作一樣。

fprintf:

函數(shù)功能:將內(nèi)存中的數(shù)據(jù)以一定的格式輸出到文件中。也就是打印,也稱為寫(xiě)。

函數(shù)原型:

int fprintf( FILE *stream, const char *format [, argument ]...);

第一個(gè)參數(shù)是文件指針,第二個(gè)參數(shù)和printf函數(shù)一樣,會(huì)用printf函數(shù)就會(huì)用這個(gè)函數(shù)。

舉例:

include <stdio.h>
#include <string.h>
#include <errno.h>
struct S
{
	char name[20];
	char sex[5];
	int age;
};
int main()
{
	//打開(kāi)文件
	FILE* pf = fopen("data.txt", "r");
	//如果文件打開(kāi)失敗,失敗返回
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 0;
	}
	//對(duì)文件進(jìn)行格式化輸入輸出操作
	struct S tmp = { 0 };
	fscanf(pf, "%s %s %d", tmp.name, tmp.sex, &(tmp.age));
	printf("%s %s %d\n", tmp.name, tmp.sex, tmp.age);
	//可以打印出來(lái),我這里沒(méi)打印。
	//關(guān)閉文件
	fclose(pf);
	pf = NULL;
	return 0;
}

二進(jìn)制輸入輸出函數(shù)fread和fwrite

fread:

函數(shù)功能:Reads data from a stream.從一個(gè)流中讀取數(shù)據(jù)到內(nèi)存中。

函數(shù)原型:

size_t fread( void *buffer, size_t size, size_t count, FILE *stream );

第一個(gè)參數(shù)是buffer是內(nèi)存的意思,第二個(gè)參數(shù)是要讀的數(shù)據(jù)的類(lèi)型,第三個(gè)參數(shù)是讀取的個(gè)數(shù),第四個(gè)參數(shù)是文件指針??偟囊馑际菑奈募羔樦赶虻奈募x取count個(gè)size大小的數(shù)據(jù)到內(nèi)存buffer中。

返回值:若在讀取過(guò)程中發(fā)生錯(cuò)誤或是在未讀取到指定元素個(gè)數(shù)時(shí)讀取到文件末尾,則返回一個(gè)小于count的數(shù)。

fwrite:

函數(shù)功能:Writes data to a stream.寫(xiě)入二進(jìn)制數(shù)據(jù)到文件中

函數(shù)原型:

size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );

第一個(gè)參數(shù)是輸出數(shù)據(jù)的位置,第二個(gè)參數(shù)是要輸出數(shù)據(jù)的元素個(gè)數(shù),第三個(gè)參數(shù)是每個(gè)元素的大小,第四個(gè)參數(shù)是數(shù)據(jù)輸出的目標(biāo)位置。返回值:該函數(shù)調(diào)用完后,會(huì)返回實(shí)際寫(xiě)入目標(biāo)位置的元素個(gè)數(shù),當(dāng)輸出時(shí)發(fā)生錯(cuò)誤或是待輸出數(shù)據(jù)元素個(gè)數(shù)小于要求輸出的元素個(gè)數(shù)時(shí),會(huì)返回一個(gè)小于count的數(shù)。

舉例:以wb輸出到文件

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	//打開(kāi)文件
	FILE* pf = fopen("data.txt", "wb");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 0;
	}
	//對(duì)文件以二進(jìn)制形式進(jìn)行輸出操作
	int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	fwrite(arr, sizeof(int), 10, pf);
	//關(guān)閉文件
	fclose(pf);
	pf = NULL;
	return 0;
}

文件的隨機(jī)讀寫(xiě)

fseek

函數(shù)介紹:定位文件指針,以文件指針當(dāng)前的位置,偏移到想定位的位置。向前偏移是負(fù)的,比如-1,-2,向后偏移是正的。

  • SEEK_CUR:從當(dāng)前指針的位置偏移
  • SEEK_SET:從文件的起始位置開(kāi)始偏移
  • SEEK_END:從文件的末尾開(kāi)始偏移

函數(shù)原型:

int fseek( FILE *stream, long offset, int origin );

第一個(gè)參數(shù)是文件指針,第二個(gè)參數(shù)是要偏移的偏移量。第三個(gè)參數(shù)是從什么位置開(kāi)始偏移。舉例。

/* fseek example */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  //打開(kāi)文件
  pFile = fopen ( "example.txt" , "wb" );
  //以一行的形式寫(xiě)文件
  fputs ( "This is an apple." , pFile );
  //讓文件指針從文件的起始位置開(kāi)始偏移9個(gè)單位。
  fseek ( pFile , 9 , SEEK_SET );
  //繼續(xù)寫(xiě)文件
  fputs ( " sam" , pFile );
  //關(guān)閉文件
  fclose ( pFile );
  return 0; 
  }

ftell

函數(shù)介紹:可以返回文件指針相對(duì)于起始位置的偏移量

函數(shù)原型:

long ftell( FILE *stream );

返回值類(lèi)型為long int,第一個(gè)參數(shù)是文件指針。

fwind

函數(shù)介紹:讓文件指針回到文件的起始位置。fseek函數(shù)也可以達(dá)到同樣的效果。

函數(shù)原型:

void rewind( FILE *stream );

舉例

/* rewind example */
#include <stdio.h>
int main ()
{
  int n;
  FILE * pFile;
  char buffer [27];
  //打開(kāi)文件
  pFile = fopen ("myfile.txt","w+");
  for ( n='A' ; n<='Z' ; n++)
   {
   	 fputc ( n, pFile);
   }
  //使指針回到起始位置
  rewind (pFile);
  fread (buffer,1,26,pFile);
  fclose (pFile);
  buffer[26]='\0';
  puts (buffer);
    return 0;
   }

文本文件和二進(jìn)制文件

數(shù)據(jù)文件:可以分為文本文件和二進(jìn)制文件

二進(jìn)制文件:文本文件可以肉眼看懂,二進(jìn)制文件則是亂碼看不懂。

數(shù)據(jù)在內(nèi)存中是以二進(jìn)制的形式存儲(chǔ),如果不加轉(zhuǎn)換的輸出到外存,就是二進(jìn)制文件文本文件:如果要求在外存中以ASCII碼的形式存儲(chǔ),則需要在存儲(chǔ)前轉(zhuǎn)換。如果以ASCII字符的形式存儲(chǔ)文件就叫做文本文件。

具體例子如下。

一個(gè)數(shù)據(jù)在內(nèi)存中是怎么存儲(chǔ)的呢?

如果整數(shù)10000以ASCII碼的形式輸出到磁盤(pán),則占用5個(gè)字節(jié)。如果以二進(jìn)制形式輸出到磁盤(pán)則占用4個(gè)字節(jié)。

在這里插入圖片描述

文件結(jié)束的判定

feof

牢記:在文件讀取過(guò)程中,不能用feof函數(shù)的返回值直接用來(lái)判斷文件是否結(jié)束。

函數(shù)功能:應(yīng)用于當(dāng)文件讀取結(jié)束的時(shí)候,用ferror判斷是讀取失敗結(jié)束,還是遇到文件末尾結(jié)束。

1.文本文件讀取是否結(jié)束,判斷返回值是否為EOF(fgetc),或者是否為NULL(fgets)等。每個(gè)函數(shù)有每個(gè)特定的結(jié)束標(biāo)志。

2.二進(jìn)制文件的讀取結(jié)束判斷,判斷返回值是否小于實(shí)際要讀的個(gè)數(shù)。

正確使用例子

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    int c;
     // 注意:int,非char,要求處理EOF
    FILE* fp = fopen("test.txt", "r");
    //如果為0,則打開(kāi)失敗
    if(!fp)
    {
        perror("File opening failed");
        return EXIT_FAILURE;
   }
 //fgetc 當(dāng)讀取失敗的時(shí)候或者遇到文件結(jié)束的時(shí)候,都會(huì)返回EOF
    while ((c = fgetc(fp)) != EOF) // 標(biāo)準(zhǔn)C I/O讀取文件循環(huán)
   { 
       putchar(c);
   }
   //feof是用來(lái)在結(jié)束后判斷是什么原因結(jié)束的
    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp))
        puts("End of file reached successfully");
    fclose(fp);
}

文件緩沖區(qū)

在ANSIC標(biāo)準(zhǔn)采用“緩沖文件系統(tǒng)”處理的數(shù)據(jù)文件的,所謂緩沖文件系統(tǒng)是指系統(tǒng)自動(dòng)的在在內(nèi)存中為程序中每一個(gè)正在使用的文件開(kāi)辟一塊“文件緩沖區(qū)”。從內(nèi)存向磁盤(pán)輸出數(shù)據(jù)會(huì)先送到內(nèi)存中的緩沖區(qū),裝滿緩沖區(qū)后才一起送到磁盤(pán)上。如果從磁盤(pán)向計(jì)算機(jī)讀入數(shù)據(jù),則從磁盤(pán)文件中讀取數(shù)據(jù)輸入到內(nèi)存緩沖區(qū)(充滿緩沖區(qū)),然后再?gòu)木彌_區(qū)逐個(gè)地將數(shù)據(jù)送到程序數(shù)據(jù)區(qū)(程序變量等)。緩沖區(qū)的大小根據(jù)C編譯系統(tǒng)決定的。

在這里插入圖片描述

舉例:C語(yǔ)言代碼也就是用戶程序,要在屏幕上打印信息。則需要調(diào)用printf函數(shù),而printf函數(shù)則調(diào)用了系統(tǒng)的API,讓操作系統(tǒng)在屏幕上打印信息。但操作系統(tǒng)要為好多程序服務(wù)。所以在操作系統(tǒng)解決前,先放到文件緩沖區(qū),程序攢滿了再交給操作系統(tǒng)解決。

結(jié)論:因?yàn)橛芯彌_區(qū)的存在,C語(yǔ)言再操作文件的時(shí)候,需要做刷新緩沖區(qū)或者在文件操作結(jié)束的時(shí)候關(guān)閉文件。如果不做,可能導(dǎo)致讀寫(xiě)文件的問(wèn)題

到此這篇關(guān)于C語(yǔ)言由淺入深講解文件的操作下篇的文章就介紹到這了,更多相關(guān)C語(yǔ)言 文件操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++類(lèi)URL編碼和解碼使用技巧

    C++類(lèi)URL編碼和解碼使用技巧

    在項(xiàng)目開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)使用到c++ 的url編碼和解碼,本文將以此問(wèn)題詳細(xì)介紹使用技巧,需要的朋友可以參考下
    2012-11-11
  • C++日期與時(shí)間 chrono庫(kù)介紹及使用教程

    C++日期與時(shí)間 chrono庫(kù)介紹及使用教程

    chrono庫(kù)是C++11中的一個(gè)標(biāo)準(zhǔn)庫(kù),它提供了一系列與時(shí)間相關(guān)的類(lèi)和函數(shù),用于表示和處理時(shí)間間隔,時(shí)鐘和時(shí)間點(diǎn),C++20新增Calendar,這篇文章主要介紹了C++日期與時(shí)間 chrono庫(kù)介紹及使用,需要的朋友可以參考下
    2023-12-12
  • Qt QMessageBox類(lèi)使用教程

    Qt QMessageBox類(lèi)使用教程

    QMessageBox類(lèi)提供一個(gè)模態(tài)對(duì)話框,用于通知用戶或詢問(wèn)用戶一個(gè)問(wèn)題并接收答案。這篇文章主要介紹了QMessageBox的一些常用用法,需要的小伙伴快來(lái)學(xué)習(xí)一下
    2021-12-12
  • C語(yǔ)言實(shí)現(xiàn)strlen的三種方法小結(jié)

    C語(yǔ)言實(shí)現(xiàn)strlen的三種方法小結(jié)

    本文主要介紹了C語(yǔ)言實(shí)現(xiàn)strlen的三種方法小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 詳解如何利用C++實(shí)現(xiàn)Mystring類(lèi)

    詳解如何利用C++實(shí)現(xiàn)Mystring類(lèi)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)MyString的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • MFC對(duì)話框?qū)崿F(xiàn)梯形分頁(yè)

    MFC對(duì)話框?qū)崿F(xiàn)梯形分頁(yè)

    這篇文章主要為大家詳細(xì)介紹了MFC對(duì)話框?qū)崿F(xiàn)梯形分頁(yè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • C++ 實(shí)現(xiàn)帶監(jiān)視哨的順序查找算法

    C++ 實(shí)現(xiàn)帶監(jiān)視哨的順序查找算法

    這篇文章主要介紹了C++ 實(shí)現(xiàn)帶監(jiān)視哨的順序查找算法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • C++?OpenCV中幾種基本的圖像處理方式

    C++?OpenCV中幾種基本的圖像處理方式

    大家好,本篇文章主要講的是C++?OpenCV中幾種基本的圖像處理方式,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • C語(yǔ)言 格式化讀寫(xiě)文件詳解

    C語(yǔ)言 格式化讀寫(xiě)文件詳解

    本文主要介紹C語(yǔ)言 格式化讀寫(xiě)文件,這里提供了關(guān)于格式化讀寫(xiě)文件的基本資料及實(shí)現(xiàn)示例代碼,有興趣的小伙伴可以參考下,以便理解學(xué)習(xí)
    2016-08-08
  • 如何用C++實(shí)現(xiàn)雙向循環(huán)鏈表

    如何用C++實(shí)現(xiàn)雙向循環(huán)鏈表

    本篇文章是對(duì)用C++實(shí)現(xiàn)雙向循環(huán)鏈表的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評(píng)論

大名县| 盈江县| 阜阳市| 桐庐县| 阆中市| 上思县| 札达县| 仙桃市| 洛南县| 尚义县| 太康县| 苗栗县| 武夷山市| 阳城县| 平潭县| 泉州市| 宝丰县| 谷城县| 昌平区| 陈巴尔虎旗| 苍山县| 梨树县| 博白县| 九龙坡区| 柳河县| 仪陇县| 凤阳县| 安达市| 岳池县| 隆子县| 泰州市| 始兴县| 威远县| 荃湾区| 南汇区| 克山县| 彰武县| 定南县| 沁阳市| 沂水县| 平遥县|