欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

1.fseek,改變該指針的指向。

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

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

1.fseek

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

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

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

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

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

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

fseek(pf, 4, SEEK_SET);

下面我們來驗(yàn)證一下。先在工程目錄下創(chuàng)建一個文件,文件名是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的第三個參數(shù)origin有三種取值,分別是:

1.SEEK_SET,表示起始位置。

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

3.SEEK_END,表示文件末尾。

SEEK_SET和SEEK_CUR都很好理解,需要注意的是,SEEK_END不是指向最后一個字符,而是指向最后一個字符的下一個位置。比如,一個文件中存有abcdefg,SEEK_END不是指向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,所以讀取時就跳過了前面的abcd,直接讀到e。說明一下,由于讀寫前該指針指向了e,調(diào)用fgetc讀完e后,該指針就指向了e后面的f,也就是說,此時SEEK_CUR就指向了f,如果我們想讀到b呢?可以數(shù)一下,abcdefg,b相對于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

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

long int ftell ( FILE * stream );

ftell會返回當(dāng)前相對于起始位置的偏移量。比如前面的例子中調(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;
}

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

3.rewind

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

void rewind ( FILE * stream );

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

在前面的例子中,記錄文件讀寫位置的指針左右橫跳,最后指向了c,此時ftell也返回了2,這時如果我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ì)上是改變一個指向文件讀寫位置的指針的指向。

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

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

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

相關(guān)文章

  • 7種排序算法的實(shí)現(xiàn)示例

    7種排序算法的實(shí)現(xiàn)示例

    這篇文章主要介紹了7種排序算法的實(shí)現(xiàn)示例,需要的朋友可以參考下
    2014-05-05
  • Opencv提取連通區(qū)域輪廓的方法

    Opencv提取連通區(qū)域輪廓的方法

    這篇文章主要為大家詳細(xì)介紹了Opencv提取連通區(qū)域輪廓的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • VC++文件監(jiān)控之ReadDirectoryChangesW

    VC++文件監(jiān)控之ReadDirectoryChangesW

    文章主要介紹文件監(jiān)控的另一種實(shí)現(xiàn)方式,利用ReadDirectoryChangesW來實(shí)現(xiàn)文件的監(jiān)控,希望對大家有幫助
    2019-04-04
  • OpenCV繪制正多邊形的方法

    OpenCV繪制正多邊形的方法

    這篇文章主要為大家詳細(xì)介紹了OpenCV繪制正多邊形的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C語言算法練習(xí)之佩奇借書

    C語言算法練習(xí)之佩奇借書

    這篇文章主要該大家分享C語言佩奇借書的練習(xí),文章主要通過描述佩奇借書的問題然后確定程序框架將結(jié)果運(yùn)算出來,下面來看詳細(xì)內(nèi)容吧,需要的朋友可以參考一下
    2022-03-03
  • 用C語言簡單實(shí)現(xiàn)掃雷小游戲

    用C語言簡單實(shí)現(xiàn)掃雷小游戲

    這篇文章主要為大家詳細(xì)介紹了用C語言簡單實(shí)現(xiàn)掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 求解旋轉(zhuǎn)數(shù)組的最小數(shù)字

    求解旋轉(zhuǎn)數(shù)組的最小數(shù)字

    這篇文章主要介紹了求解旋轉(zhuǎn)數(shù)組的最小數(shù)字的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • MFC程序設(shè)計常用技巧匯總

    MFC程序設(shè)計常用技巧匯總

    這篇文章主要介紹了MFC程序設(shè)計常用技巧,實(shí)例匯總了MFC程序設(shè)計中常見的問題與解決方法,非常具有實(shí)用價值,需要的朋友可以參考下
    2015-05-05
  • 一篇文章帶你了解C++的KMP算法

    一篇文章帶你了解C++的KMP算法

    這篇文章主要介紹了c++ 實(shí)現(xiàn)KMP算法的示例,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下,希望能給你帶來幫助
    2021-08-08
  • VC6.0代碼自動提示 VC6.0在win7環(huán)境下代碼提示智能化

    VC6.0代碼自動提示 VC6.0在win7環(huán)境下代碼提示智能化

    作為程序猿的你,是否已經(jīng)喜歡或習(xí)慣依賴IDE開發(fā)環(huán)境呢,有了IDE環(huán)境,即使你想不起方法全名,只要知道某個前綴,或哪怕在提示列表中,一一查詢,也可以找到自己想找的方法或?qū)傩?/div> 2013-01-01

最新評論