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

4組C語言中順序讀寫文件的函數(shù)分享

 更新時間:2023年03月31日 09:16:53   作者:努力學(xué)習(xí)游泳的魚  
這篇文章主要為大家詳細(xì)介紹了4組C語言中實(shí)現(xiàn)順序讀寫文件的函數(shù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

預(yù)備知識:fopen和fclose

如果我們要讀寫一個文件,就必須先打開這個文件,讀寫完后,還需要關(guān)閉這個文件。這就像,你要喝一杯水,需要先打開杯蓋,才能喝水,喝完水后還需要把蓋子蓋上。

打開文件的原理是,打開文件后,在內(nèi)存中創(chuàng)建一個FILE類型的變量,用來記錄打開的文件的相關(guān)信息。FILE類型是一個結(jié)構(gòu)體類型。

關(guān)閉文件的原理是,根據(jù)這個FILE類型的變量里描述的文件信息,通過一定手段把文件關(guān)閉。

在學(xué)習(xí)C語言的過程中,我們不需要知道具體的細(xì)節(jié),會用就行了。C語言中打開文件需要使用函數(shù)fopen,關(guān)閉文件需要使用函數(shù)fclose。

fopen的聲明如下:

FILE * fopen ( const char * filename, const char * mode );

看這個聲明,可以了解到,第一個參數(shù)就是要打開文件的文件名,第二個參數(shù)是用什么方式打開(讀?寫?還是其他模式?)。函數(shù)會打開這個文件,在內(nèi)存中創(chuàng)建一個相對應(yīng)的文件信息區(qū),其實(shí)就是創(chuàng)建一個FILE類型的變量,這個變量記錄了文件的相關(guān)信息。接著,這個函數(shù)會返回這個FILE變量的地址,如果函數(shù)打開文件失敗會返回NULL指針。

這里為了簡單起見,都在工程目錄下操作文件,所以文件名不用帶上路徑。如果要在其他位置操作文件,根據(jù)具體情況帶上絕對路徑或者相對路徑就可以了。

假設(shè)我們要操作的文件的文件名是test.txt,我們想要寫這個文件(寫文件的模式是"w",及write的簡寫),可以這么調(diào)用這個函數(shù):

FILE* pf = fopen("test.txt", "w");

這里的2個參數(shù)都用雙引號引起,因?yàn)槭亲址?。返回值需要使用一個FILE*的指針來接收。和malloc類似,需要檢查返回值是否為NULL指針,如果為NULL指針,則打開文件失敗,需要進(jìn)行錯誤處理,舉個例子:

if (pf == NULL)
{
    perror("fopen");
    exit(1);
}

以上的代碼中,當(dāng)檢查到pf為NULL,此時打開文件失敗,用perror報個錯,再exit掉,終止進(jìn)程。

當(dāng)然,操作文件不只有"w"一種模式。本篇博客主要介紹比較常見的4種模式,分別是:

  • “w” - 寫文件,即write的簡寫。
  • “r” - 讀文件,即read的簡寫。
  • “wb” - 通過二進(jìn)制的方式寫文件,b是binary的縮寫。
  • “rb” - 通過二進(jìn)制的方式讀文件。

fclose函數(shù)的聲明如下:

int fclose ( FILE * stream );

具體的使用很簡單,前面我們用一個FILE*的指針來接收fopen函數(shù)的返回值,只需要把這個指針傳給fclose就能關(guān)閉對應(yīng)的文件了。和free函數(shù)類似,fclose函數(shù)沒有能力把傳給它的指針置為NULL,為了防止野指針,需要程序員手動置為NULL值。

fclose(pf);
pf = NULL;

1.字符讀寫:fputc和fgetc

fputc用于向文件中寫入一個字符。

讀寫文件前,應(yīng)該打開文件。這次以"w"的模式打開。

FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
    perror("fopen");
    exit(1);
}

接下來是使用fputc寫文件的操作。寫完文件后,需要關(guān)閉文件。

fclose(pf);
pf = NULL;

后面的函數(shù)都是按照打開文件->讀寫文件->關(guān)閉文件的順序,唯一的區(qū)別是打開文件的方式不一樣,也就是fopen的第二個參數(shù)不一樣。

fputc的聲明如下:

int fputc ( int character, FILE * stream );

很明顯,第一個參數(shù)表示寫入的字符,第二個參數(shù)表示指向文件信息區(qū)的文件指針。比如,如果我要把字符’a’寫到pf對應(yīng)的文件里,應(yīng)該這么寫:

fputc('a', pf);

舉一反三:如果要把小寫的a~z,總共26個字母寫到文件中,應(yīng)該如何寫呢?

for (int ch = 'a'; ch <= 'z'; ch++)
{
    fputc(ch, pf);
}

程序執(zhí)行的結(jié)果是:創(chuàng)建了一個test.txt文件,并寫入了a~z。

接下來,我們來讀一下這個文件。使用fgetc之前也需要打開文件,打開的模式是"r",使用完后需要關(guān)閉文件。

fgetc是用來讀取一個字符的。聲明如下:

int fgetc ( FILE * stream );

函數(shù)會讀一個字符然后返回這個字符的ASCII碼值。如果讀取失敗會返回EOF。

如果想讀取剛剛寫完的文件,把26個字母讀出來,可以使用循環(huán)讀26次,但是如果不知道文件中有多少字符呢?那就一直讀取,直到讀完為止。那如何判斷讀取結(jié)束呢?當(dāng)fgetc返回EOF的時候讀取就結(jié)束了。

int ch = 0;
while ((ch = fgetc(pf)) != EOF)
{
    printf("%c ", ch);
}

運(yùn)行結(jié)果如下:

2.文本行讀寫:fputs和fgets

使用fputs之前,要以"w"的模式打開文件,使用完后要關(guān)閉文件,操作同上。

fputs是用來寫入文本行的,聲明如下:

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

str表示要寫入的字符串。比如,我寫10行Hello, world!!!進(jìn)去,每寫一個就換個行。

for (int i = 0; i < 10; i++)
{
    fputs("Hello, world!!!\n", pf);
}

可以發(fā)現(xiàn),test.txt中就有了10行Hello, world!!!。

想把它們讀出來,可以使用fgets,打開文件的模式是"r"。聲明如下:

char * fgets ( char * str, int num, FILE * stream );

str表示你想把讀到的字符串存在哪,num表示存儲的空間有多大(最多存多少個字符,包括字符串結(jié)尾的’\0’)。函數(shù)會把str返回回來,如果讀取失敗,會返回NULL指針。所以讀取時,可以使用循環(huán),通過每次判斷返回值是否為NULL指針,來判斷是否讀取結(jié)束。

char str[256] = {0};
while (fgets(str, 256, pf))
{
    puts(str);
}

輸出結(jié)果:

由于寫入時每個Hello, world!!!后面都寫了個’\n’,而puts會在打印完字符串后也換個行,所以相當(dāng)于每次打印完Hello, world!!!后面都換2次行。如果你只想換一次行,可以使用printf來實(shí)現(xiàn):

    char str[256] = { 0 };
    while (fgets(str, 256, pf))
    {
        printf("%s", str);
    }

輸出結(jié)果如下:

3.格式化讀寫:fprintf和fscanf

fprintf和fscanf,與printf和scanf非常像,唯一的區(qū)別就是,fprintf和fscanf前面多了個f。(emmm,聽君一席話,如聽一席話)

在學(xué)習(xí)這兩個函數(shù)之前,建議先學(xué)一下sprintf和sscanf這兩個函數(shù),點(diǎn)這里

我還是采取同樣的講解思路。你也許不知道fprintf和sscanf,但你一定知道printf和scanf(別告訴我你不知道)。

先說printf。舉個例子,假設(shè)有一個結(jié)構(gòu)體:

struct S
{
    int i;
    double d;
    char arr[30];
};

我創(chuàng)建了一個結(jié)構(gòu)體變量:

struct S s = {10, 3.14, "abcdef"};

我想你把這個結(jié)構(gòu)體的數(shù)據(jù)用printf打印到屏幕上,你會怎么寫?

printf("%d %lf %s\n", s.i, s.d, s.arr);

如果這些數(shù)據(jù)不是打印到屏幕上,而是“打印”到文件中,只需要在函數(shù)名前面加個f,所有參數(shù)最前面加個pf,就行了。

fprintf(pf, "%d %lf %s\n", s.i, s.d, s.arr);

簡單吧?注意fprintf需要的打開文件方式是"w",使用完后需要關(guān)閉文件。來看看此時的test.txt文件:

干得漂亮!接下來來看看fscanf。fscanf使用前需要使用"r"模式打開文件,使用完后需要關(guān)閉文件,都學(xué)到這了,別忘了?。ㄉ陨钥偨Y(jié)一下,目前所有寫文件操作打開文件的模式都是"w",即write的簡寫,而讀文件操作打開文件的模式都是"r",即read的縮寫。)

還是那句話,你也許沒有聽說過fscanf,但你一定直到scanf。假設(shè)我創(chuàng)建了一個結(jié)構(gòu)體變量:

struct S s = {0};

我想你用scanf函數(shù),實(shí)現(xiàn)從鍵盤中輸入數(shù)據(jù)到s中,你會怎么寫?

scanf("%d %lf %s", &s.i, &s.d, s.arr);

如果不是從鍵盤中輸入數(shù)據(jù),而是從文件中讀取數(shù)據(jù),只需要在函數(shù)名前加個f,參數(shù)最前面加個pf就行了。

fscanf(pf, "%d %lf %s", &s.i, &s.d, s.arr);

讀完之后,我們可以把s中的數(shù)據(jù)打印出來。

printf("%d %lf %s\n", s.i, s.d, s.arr);

看吧,讀取成功了。

4.二進(jìn)制讀寫:fwrite和fread

前面我們都是讀寫字符文件,也就是以字符的形式讀寫文件,這是我們能看的懂的形式。但是在計算機(jī)的世界中,都是二進(jìn)制的,所以我們還需要學(xué)習(xí)用二進(jìn)制的方式來讀寫文件。

先來學(xué)習(xí)下fwrite。由于是二進(jìn)制的形式讀寫文件,打開文件的模式是"wb",b代表二進(jìn)制。函數(shù)的聲明如下:

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

fwrite函數(shù)和fread函數(shù)的參數(shù)列表是一樣的,所以學(xué)會一個就相當(dāng)于兩個都學(xué)會了。第一個參數(shù)表示你要寫入的數(shù)據(jù)在內(nèi)存中存儲的位置,第二個參數(shù)表示寫入一個數(shù)據(jù)的大小,第三個參數(shù)表示要寫入幾個數(shù)據(jù)。

比如,我有一個結(jié)構(gòu)體變量:

struct S s = {10, 3.14, "abcdef"};

我想把它以二進(jìn)制的形式寫到內(nèi)存中,第一個參數(shù)就是s的地址,第二個參數(shù)就是一個結(jié)構(gòu)體的大小,由于我只想寫1個s進(jìn)去,所以第三個參數(shù)就是1。

fwrite(&s, sizeof(s), 1, pf);

輸出結(jié)果:

看不懂呀!很正常,因?yàn)檫@玩意是二進(jìn)制。接下來我們用二進(jìn)制的方式來把數(shù)據(jù)重新讀出來。

fread是用來二進(jìn)制的讀文件的,打開文件的模式是"rb",使用完后需要關(guān)閉文件。函數(shù)的聲明如下:

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

第一個參數(shù)表示要把讀到的數(shù)據(jù)存到哪,第二個參數(shù)表示讀取一個數(shù)據(jù)的大小,第三個參數(shù)表示要讀幾個數(shù)據(jù)。

比如,我們先創(chuàng)建一個結(jié)構(gòu)體:

struct S s = {0};

接著把讀到的數(shù)據(jù)放到s里,有了前面fwrite的經(jīng)驗(yàn),寫起來就簡單了。

fread(&s, sizeof(s), 1, pf);

接著把s中的數(shù)據(jù)打印出來:

printf("%d %lf %s\n", s.i, s.d, s.arr);

輸出結(jié)果如下:

5.格局打開

其實(shí),我們可以把“屏幕”和“鍵盤”也當(dāng)成文件。用stdout表示屏幕,stdin表示鍵盤,舉個例子:

fprintf(stdout, "%d %lf %s\n", s.i, s.d, s.arr);

這行代碼會把結(jié)構(gòu)體s中的數(shù)據(jù)寫入到stdout這個“文件”中,而stdout表示屏幕,所以也就把結(jié)構(gòu)體中的數(shù)據(jù)打印到屏幕上了!哈哈哈,有意思吧。

其實(shí),stdout是標(biāo)準(zhǔn)輸出流,而stdin是標(biāo)準(zhǔn)輸入流。在前面的函數(shù)中,只要是以"w"模式打開文件才能使用的函數(shù)(fputc, fputs, fprintf)的FILE*類型的參數(shù)就可以傳stdout,而以"r"模式打開文件才能使用的函數(shù)(fgetc, fgets, fscanf)的FILE*類型的參數(shù)就可以傳stdin,分別表示“寫屏幕”(把數(shù)據(jù)打印到屏幕上)和“讀鍵盤”(從鍵盤中輸入數(shù)據(jù))。

你可能納悶了,為啥stdout和stdin就不用有fopen和fclose這樣的操作呢?這是因?yàn)椋灰粋€C程序跑起來,就默認(rèn)打開了三個流,分別是:stdout(標(biāo)準(zhǔn)輸出流),stdin(標(biāo)準(zhǔn)輸入流)和stderr(標(biāo)準(zhǔn)錯誤流),所以不需要我們手動打開。

這時,你再想想,printf和fprintf有什么區(qū)別?區(qū)別就是,printf只能格式化輸出標(biāo)準(zhǔn)輸出流的數(shù)據(jù),而fprintf可以格式化輸出任意輸出流的數(shù)據(jù)(包括標(biāo)準(zhǔn)輸出流和文件流);同理,scanf和fscanf的區(qū)別是,scanf只能格式化輸入標(biāo)準(zhǔn)輸入流中的數(shù)據(jù),而fscanf可以輸入任意輸入流的數(shù)據(jù)(包括標(biāo)準(zhǔn)輸入流和文件流)。那sprintf和sscanf和它們之間有什么區(qū)別呢?這兩個函數(shù)是用來進(jìn)行格式化數(shù)據(jù)和字符串的相互轉(zhuǎn)換的,就跟這些“流”沒什么關(guān)系了。

到此這篇關(guān)于4組C語言中順序讀寫文件的函數(shù)分享的文章就介紹到這了,更多相關(guān)C語言順序讀寫文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于C語言編寫簡易的英文統(tǒng)計和加密系統(tǒng)

    基于C語言編寫簡易的英文統(tǒng)計和加密系統(tǒng)

    這篇文章主要介紹如何基于C語言編寫一個簡易的英文統(tǒng)計和加密系統(tǒng),實(shí)際上就是對字符數(shù)組的基本操作的各種使用,感興趣的可以了解一下
    2023-05-05
  • FFmpeg實(shí)現(xiàn)多線程編碼并保存mp4文件

    FFmpeg實(shí)現(xiàn)多線程編碼并保存mp4文件

    這篇文章主要為大家介紹了FFmpeg如何持續(xù)的從指定內(nèi)存中讀取原始數(shù)據(jù),再將解碼數(shù)據(jù)存入隊(duì)列中,并通過單獨(dú)的線程進(jìn)行編碼,最后保存為mp4文件,感興趣的可以了解下
    2023-08-08
  • C++實(shí)現(xiàn)乒乓球比分判定

    C++實(shí)現(xiàn)乒乓球比分判定

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)乒乓球比分判定,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • mingw編譯的windows命令行貪吃蛇示例

    mingw編譯的windows命令行貪吃蛇示例

    這篇文章主要介紹了mingw編譯的windows命令行貪吃蛇示例,需要的朋友可以參考下
    2014-04-04
  • C++實(shí)現(xiàn)動態(tài)規(guī)劃過程詳解

    C++實(shí)現(xiàn)動態(tài)規(guī)劃過程詳解

    動態(tài)規(guī)劃是解決一類最優(yōu)問題的常用方法,它是解決最優(yōu)化問題的一種途徑,在本文中,我們將討論如何使用C++實(shí)現(xiàn)動態(tài)規(guī)劃算法,并提供一些示例來幫助您更好地理解該算法
    2023-05-05
  • memset函數(shù)的使用分析

    memset函數(shù)的使用分析

    本篇文章是對memset函數(shù)的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++ 如何使用RapidJson 寫入文件

    C++ 如何使用RapidJson 寫入文件

    RapidJSON 是只有頭文件的 C++ 庫, 不需要編譯, 可以直接在項(xiàng)目中使用, 只需把 include/rapidjson 目錄復(fù)制至系統(tǒng)或項(xiàng)目的 include 目錄即可,下面給大家分享C++ 如何使用RapidJson 寫入文件,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • C語言執(zhí)行程序時遇到的常見問題及解決

    C語言執(zhí)行程序時遇到的常見問題及解決

    這篇文章主要介紹了C語言執(zhí)行程序時遇到的常見問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • C++ Primer中&、*符號的多重定義與int *p和int* p的區(qū)別講解

    C++ Primer中&、*符號的多重定義與int *p和int* p的區(qū)別講解

    今天小編就為大家分享一篇關(guān)于C++Primer中&、*符號的多重定義與int *p和int* p的區(qū)別講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • C語言數(shù)字圖像處理之圖像縮放

    C語言數(shù)字圖像處理之圖像縮放

    這篇文章主要為大家詳細(xì)介紹了C語言數(shù)字圖像處理之圖像縮放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10

最新評論

钟祥市| 临沧市| 泗洪县| 灌云县| 内丘县| 长治县| 斗六市| 合川市| 凤翔县| 南通市| 郓城县| 冷水江市| 博湖县| 南皮县| 阿拉尔市| 东平县| 通许县| 大荔县| 稷山县| 循化| 鹤庆县| 文水县| 清丰县| 芜湖县| 丘北县| 贡嘎县| 罗山县| 黄浦区| 银川市| 鹿邑县| 贵定县| 铁岭市| 互助| 清流县| 安宁市| 广州市| 从江县| 清镇市| 清远市| 社会| 眉山市|