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

C語言實(shí)現(xiàn)隨機(jī)讀寫文件的函數(shù)詳解

 更新時(shí)間:2023年03月31日 14:29:37   作者:努力學(xué)習(xí)游泳的魚  
文件的隨機(jī)讀寫,可以在文件中指定的任意位置讀或者寫。這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)隨機(jī)讀寫文件的3個(gè)函數(shù),感興趣的可以了解一下

上一篇博客中,我詳細(xì)講解了如何使用C語言順序讀寫文件。所謂順序讀寫,就是按照順序,挨個(gè)挨個(gè)的讀或者寫,換句話說,我必須先讀第一個(gè),再讀第二個(gè),接著讀第三個(gè),以此類推,而不能一上來就讀第五個(gè)。這樣就不夠靈活,因?yàn)橛袝r(shí)候我們想讀寫文件的任意位置。這就需要使用文件的隨機(jī)讀寫。

文件的隨機(jī)讀寫,可以在文件中指定的任意位置讀或者寫。這是怎么做到的呢?事實(shí)上,當(dāng)我們順序讀寫文件時(shí),文件中會(huì)有一個(gè)指針記錄你讀(或者寫)到哪了。比如,一個(gè)文件里存著"abcdefg",當(dāng)我們打開文件時(shí),這個(gè)指針默認(rèn)指向了第一個(gè)字符a,當(dāng)你用fgetc讀完a后,這個(gè)指針就指向了下一個(gè)字符b,當(dāng)你再使用fgetc讀取文件時(shí)就讀到了b,以此類推。如果我們想一上來就讀e,除了按照順序讀寫的方法,把前面的abcd全都讀走,還有一種方法,直接讓這個(gè)指針指向e,就可以了。

所以,文件的隨機(jī)讀寫,本質(zhì)上是改變記錄讀寫位置的指針的指向,就能夠讀寫任意位置了。下面我們將學(xué)習(xí)與此相關(guān)的3個(gè)函數(shù),分別是:

1.fseek,改變?cè)撝羔樀闹赶颉?/p>

2.ftell,獲取該指針相對(duì)于起始位置的偏移量。

3.rewind,使文件指針指向起始位置。

1.fseek

前面已經(jīng)劇透過了,fseek可以改變記錄讀寫位置的指針的指向,從而實(shí)現(xiàn)文件的隨機(jī)讀寫。該函數(shù)的聲明如下:

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

第一個(gè)參數(shù)大家都很熟悉了,就是一個(gè)文件指針,告訴fseek我現(xiàn)在操作的是哪個(gè)文件。

第二個(gè)參數(shù),offset是偏移量的意思,大家先記住。第三個(gè)參數(shù),origin,顧名思義,即“起始位置”。后面兩個(gè)參數(shù)讓人摸不著頭腦,但是配合起來就很有意思了。

舉個(gè)例子:假設(shè)一個(gè)文件中存有abcdefg,當(dāng)你用fopen打開這個(gè)文件時(shí),一個(gè)記錄讀寫位置的指針就指向了起始位置,也就是指向了a。如果我想讀取第5個(gè)字符,即e呢?那我就要讓這個(gè)指針指向e,這樣再fgetc就能讀到e了。

我可以這樣算:e相對(duì)于起始位置a,向右偏移了4個(gè)字符,因?yàn)橄鄬?duì)于a,a自己的偏移量是0,b是1,c是2,d是3,e自然是4。那么,偏移量offset(fseek的第二個(gè)參數(shù))就是4,這個(gè)4是相對(duì)于起始位置的,這個(gè)“相對(duì)于”哪里,也就是origin(fseek的第三個(gè)參數(shù))的位置,此時(shí)origin就是“起始位置”,明白了吧。而fseek用一個(gè)宏SEEK_SET來表示“起始位置”,所以此時(shí)fseek的調(diào)用如下:

fseek(pf, 4, SEEK_SET);

下面我們來驗(yàn)證一下。先在工程目錄下創(chuàng)建一個(gè)文件,文件名是test.txt,然后在里面輸入abcdefg。

按照打開文件->讀文件->關(guān)閉文件的順序,寫代碼:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fseek(pf, 4, SEEK_SET);
	putchar(fgetc(pf));

	fclose(pf);
	pf = NULL;

	return 0;
}

打開文件后,使用fseek讓記錄讀寫位置的指針指向e,接著用fgetc讀取e并用putchar打印出來,輸出結(jié)果如下:

我們就成功跳過了前面的abcd,直接讀取到e,實(shí)現(xiàn)了文件的隨機(jī)讀寫。

當(dāng)然,讀取到e不止有這一種寫法。fseek的第三個(gè)參數(shù)origin有三種取值,分別是:

1.SEEK_SET,表示起始位置。

2.SEEK_CUR,表示當(dāng)前指向的位置。

3.SEEK_END,表示文件末尾。

SEEK_SET和SEEK_CUR都很好理解,需要注意的是,SEEK_END不是指向最后一個(gè)字符,而是指向最后一個(gè)字符的下一個(gè)位置。比如,一個(gè)文件中存有abcdefg,SEEK_END不是指向g,而是指向g的下一個(gè)位置。所以同樣是讀到e,如果origin是SEEK_END,offset就應(yīng)該是-3,因?yàn)間的偏移量是-1,f是-2,所以e是-3。把上面代碼中的fseek的調(diào)用方式改一下,其他不變:

fseek(pf, -3, SEEK_END);

也可以讀到e,因?yàn)樵趫?zhí)行完上面這行代碼后,記錄讀寫位置的指針就指向了e,所以讀取時(shí)就跳過了前面的abcd,直接讀到e。說明一下,由于讀寫前該指針指向了e,調(diào)用fgetc讀完e后,該指針就指向了e后面的f,也就是說,此時(shí)SEEK_CUR就指向了f,如果我們想讀到b呢?可以數(shù)一下,abcdefg,b相對(duì)于SEEK_CUR(指向f)的偏移量就是-4,如果像下面的代碼這樣寫:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fseek(pf, -3, SEEK_END); // 指向e
	putchar(fgetc(pf)); // 讀完e后指向f

	fseek(pf, -4, SEEK_CUR); // 指向b
	putchar(fgetc(pf)); // 讀完b后指向c

	fclose(pf);
	pf = NULL;

	return 0;
}

輸出結(jié)果如下:

2.ftell

我如果想知道此時(shí)記錄讀寫位置的指針相對(duì)于起始位置的偏移量(即相對(duì)于SEEK_SET的偏移量)是多少,就可以問問ftell函數(shù)。該函數(shù)聲明如下:

long int ftell ( FILE * stream );

ftell會(huì)返回當(dāng)前相對(duì)于起始位置的偏移量。比如前面的例子中調(diào)用:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fseek(pf, -3, SEEK_END); // 指向e
	putchar(fgetc(pf)); // 讀完e后指向f

	fseek(pf, -4, SEEK_CUR); // 指向b
	putchar(fgetc(pf)); // 讀完b后指向c

	printf("\n%ld\n", ftell(pf));

	fclose(pf);
	pf = NULL;

	return 0;
}

由于此時(shí)記錄文件讀寫位置的指針指向了c,偏移量是2(a為0,b為1,c為2),所以會(huì)輸出2。

3.rewind

rewind的作用是,讓指向文件讀寫位置的指針指向文件的起始位置。該函數(shù)聲明如下:

void rewind ( FILE * stream );

其實(shí)非常簡(jiǎn)單,rewind(pf);和fseek(pf, 0, SEEK_SET);是等價(jià)的。

在前面的例子中,記錄文件讀寫位置的指針左右橫跳,最后指向了c,此時(shí)ftell也返回了2,這時(shí)如果我rewind一下,該指針就又指向了起始位置,即a,再ftell就能知道偏移量回到了0,如果再fgetc,就能重新讀取到a了。代碼如下:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fseek(pf, -3, SEEK_END); // 指向e
	putchar(fgetc(pf)); // 讀完e后指向f

	fseek(pf, -4, SEEK_CUR); // 指向b
	putchar(fgetc(pf)); // 讀完b后指向c

	printf("\n%ld\n", ftell(pf));

	rewind(pf);
	printf("%ld\n", ftell(pf));
	putchar(fgetc(pf)); // a

	fclose(pf);
	pf = NULL;

	return 0;
}

輸出結(jié)果:

當(dāng)然,把上述代碼中的rewind(pf);換成fseek(pf, 0, SEEK_SET);的效果是一樣的。

總結(jié)

1.文件的隨機(jī)讀寫本質(zhì)上是改變一個(gè)指向文件讀寫位置的指針的指向。

2.使用fseek和rewind函數(shù)可以做到(1)這一點(diǎn)。其中,fseek需要知道該指針需要指向的新的位置,具體需要一個(gè)相對(duì)于某起始位置(origin)的偏移量(offset),其中origin可以取值為SEEK_SET(文件的起始位置),SEEK_END(文件的結(jié)束位置)和SEEK_CUR(當(dāng)前位置)。rewind函數(shù)會(huì)讓該指針直接指向SEEK_SET,所以rewind(pf);等價(jià)于fseek(pf, 0, SEEK_SET);。

3.使用ftell函數(shù)可以獲取當(dāng)前該指針相對(duì)于起始位置的偏移量。

到此這篇關(guān)于C語言實(shí)現(xiàn)隨機(jī)讀寫文件的函數(shù)詳解的文章就介紹到這了,更多相關(guān)C語言隨機(jī)讀寫文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言代碼實(shí)現(xiàn)俄羅斯方塊

    C語言代碼實(shí)現(xiàn)俄羅斯方塊

    這篇文章主要為大家詳細(xì)介紹了C語言代碼實(shí)現(xiàn)俄羅斯方塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • 使用C語言的fork()函數(shù)在Linux中創(chuàng)建進(jìn)程的實(shí)例講解

    使用C語言的fork()函數(shù)在Linux中創(chuàng)建進(jìn)程的實(shí)例講解

    這篇文章主要介紹了使用C語言的fork()函數(shù)在Linux中創(chuàng)建進(jìn)程的實(shí)例講解,fork在父進(jìn)程下創(chuàng)建出的子進(jìn)程可以與父進(jìn)程一起來多進(jìn)程運(yùn)行同一個(gè)程序,需要的朋友可以參考下
    2016-06-06
  • C++實(shí)現(xiàn)日期類(Date)

    C++實(shí)現(xiàn)日期類(Date)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)日期類的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • C++實(shí)現(xiàn)計(jì)算器功能

    C++實(shí)現(xiàn)計(jì)算器功能

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • c++和python實(shí)現(xiàn)順序查找實(shí)例

    c++和python實(shí)現(xiàn)順序查找實(shí)例

    這篇文章主要介紹了c++和python實(shí)現(xiàn)順序查找實(shí)例,流程即將目標(biāo)數(shù)值和數(shù)據(jù)庫(kù)中的每個(gè)數(shù)值進(jìn)行比較,如果相同則搜索完成,如果不同則繼續(xù)比較下一處,下面來看看具體的實(shí)例操作吧,需要的朋友可以參考一下
    2022-03-03
  • C語言中野指針和空指針的區(qū)別

    C語言中野指針和空指針的區(qū)別

    本文主要介紹了野指針和空指針的概念、用途、原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • QT6安裝圖文教程(兼容QT5、QT4)

    QT6安裝圖文教程(兼容QT5、QT4)

    本文主要介紹了QT6安裝圖文教程(兼容QT5、QT4),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 深入理解C++中的vector類的用法及特性

    深入理解C++中的vector類的用法及特性

    vector直接翻譯過來為向量,在C++中為封裝動(dòng)態(tài)數(shù)組的容器,且有序,需要的朋友可以參考下
    2016-05-05
  • C語言的數(shù)組與指針可以這樣了解

    C語言的數(shù)組與指針可以這樣了解

    這篇文章主要介紹了C語言的數(shù)組與指針,本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下,希望能給你帶來幫助
    2021-08-08
  • C語言通過案例講解并發(fā)編程模型

    C語言通過案例講解并發(fā)編程模型

    所謂并發(fā)編程是指在一臺(tái)處理器上“同時(shí)”處理多個(gè)任務(wù)。并發(fā)是在同一實(shí)體上的多個(gè)事件。多個(gè)事件在同一時(shí)間間隔發(fā)生,下面我們根據(jù)樣例來理解
    2022-04-04

最新評(píng)論

宿松县| 宁津县| 辛集市| 巴楚县| 贺州市| 酒泉市| 应城市| 海安县| 长春市| 平陆县| 定安县| 田东县| 当雄县| 天柱县| 周口市| 集安市| 高台县| 凤冈县| 广州市| 隆化县| 合川市| 绥滨县| 兴国县| 台东县| 拜泉县| 泰宁县| 当涂县| 咸丰县| 灵宝市| 武宁县| 中山市| 黎平县| 霍林郭勒市| 永清县| 枣阳市| 靖西县| 谢通门县| 江西省| 磐石市| 卢龙县| 扶风县|