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

C語言實現(xiàn)文件讀寫操作的幾種常用方法

 更新時間:2024年03月07日 10:08:43   作者:dlpmmk  
C語言提供了一系列文件操作函數(shù),使得我們可以通過程序?qū)ξ募M行讀寫操作,本文主要介紹了C語言實現(xiàn)文件讀寫操作的幾種常用方法,具有一定的參考價值,感興趣的可以了解一下

一 、文件讀寫的常用函數(shù)

(1) 讀寫文本文件:

讀文本文件 :一般都使用 getc 、fgets 、fscanf 函數(shù)

使用getc讀文件

#include <stdio.h>
int main()
{
    char a[20] = "a.txt";
    FILE *p = fopen(a,"r");
    if(p)
    {
        char c;
        while(1)
        {
            c = getc(p);
            if(c == EOF)
                break;
            printf("%c",c);
        }
        printf("\n");
        fclose(p);
    }
    else
    {
        printf("fail\n");
    }
    return 0;
}

使用fgets讀文件

#include <stdio.h>
int main()
{
    FILE *p = fopen("test.txt","r");
    if(p == NULL)
        return 0;
    char temp[1024];
    fgets(temp,sizeof(temp),p);
    while(!feof(p))
    {
        printf("%s",temp);
        fgets(temp,sizeof(temp),p);
    }
    fclose(p);
    return 0;
}

使用fscanf讀文件

#include <stdio.h>
int main()
{
    FILE *p = fopen("a.txt", "r");
    if(p == NULL)
    {
        printf("the file is close!");
        return 0;
    }
    char str1[200], str2[200], str3[200];
    int year;
    int status = fscanf(p, "%s %s %s %d", str1, str2, str3, &year); 
    while(!feof(p))
    {
        printf("%s %s %d %d status = %d\n", str1, str2, str3, year, status);
        status = fscanf(p, "%s %s %s %d", str1, str2, str3, &year);
    }
    fclose(p);
    return 0;
}

寫文本文件 :一般都使用 putc 、 fputs、fprintf 函數(shù)

使用putc寫文件

#include <stdio.h>
int main()
{
    FILE *p = fopen("a.txt","w");
    if(p)
    {
        putc('h',p);
        fclose(p);
    }
    return 0;
}

使用fputs寫文件

#include <stdio.h>
int main()
{
    FILE *p = fopen("abc.c","w");
    if(p)
    {
        fputs("#include <stdio.h>\nint main()\n{\nprintf(\"hello world\\n\");\nreturn 0;\n}",p);
        fclose(p);
    }
    return 0;
}

使用fprintf寫文件

#include <stdio.h>
#include <string.h>
int main()
{
    FILE *p = fopen("a.txt","w");
    char buf[1024];
    fgets(buf, sizeof(buf), stdin);
    while(strcmp(buf,"exit\n") != 0)
    {
       fprintf(p, "%s", buf);
       fgets(buf, sizeof(buf), stdin); 
    }
    fclose(p);
    return 0;
}

(2) 讀寫二進制文件

讀二進制文件: 使用fread 函數(shù)

代碼:

#include <stdio.h>
void readFile()
{
    FILE *p = fopen("a.txt", "rb");
    char buf[20] = { 0 };
    int index = 0;
    while(1)
    {
        int res = fread(buf, 1, 5, p);
        printf("res = %d , ", res);
        if(feof(p))
            break;
        printf("buf = %s\n",buf);
        index++;
    }
    fclose(p);
    printf("%d\n", index);
}
int main()
{
    readFile();
    return 0;
}

寫二進制文件: 使用fwrite 函數(shù)

代碼

#include <stdio.h>
void writeFile()
{
    FILE *p = fopen("b.txt", "w");
    char buf = 'a';
    int i;
    for(i = 0; i < 10 ; i++)
    {
        fwrite(&buf, 1, 1, p);
        buf++;
    }
    fclose(p);
}
int main()
{
    writeFile();
    return 0;
}

二、文件讀寫的深層次的剖析

(1)操作系統(tǒng)與硬件儲存

眾所周知,我們的計算機操作系統(tǒng)都是由C語言寫的,通過C語言協(xié)調(diào)物理內(nèi)存與虛擬內(nèi)存,操作系統(tǒng)想要向物理內(nèi)存中寫數(shù)據(jù)的時候,會費很大的力。

寫數(shù)據(jù)到物理內(nèi)存

當操作系統(tǒng)有一個字節(jié)的數(shù)據(jù)想要寫入物理磁盤中,首先要經(jīng)歷一下幾個步驟:

  • 調(diào)用CPU的控制器,發(fā)出存儲請求。
  • 控制器把將要存儲的數(shù)據(jù)放入臨時寄存器。
  • 查看總線是否被占用,請求總線控制。
  • 往地址總線發(fā)送將要使用的一個字節(jié)的空間指定。
  • 講數(shù)據(jù)寄存器中數(shù)據(jù)發(fā)送到數(shù)據(jù)總線上,傳輸?shù)较纫徊秸业降奈锢淼刂贰?/li>
  • 存儲完畢,釋放總線。

從磁盤中讀數(shù)據(jù)

讀數(shù)據(jù)的操作與寫數(shù)據(jù)的操作正好相反,也是要經(jīng)歷總線請求與總線釋放的過程。

總之,操作系統(tǒng)想要往磁盤中讀寫數(shù)據(jù)要經(jīng)歷很繁瑣的過程。

(2)操作系統(tǒng)封裝讀寫數(shù)據(jù)函數(shù)接口

每次操作系統(tǒng)與磁盤進行數(shù)據(jù)交互的時候,都會對CPU有一系列的操作指令,這些讀寫指令的合集就是讀寫函數(shù),通過C語言實現(xiàn)這些讀寫函數(shù)再往外部拋出一系列的接口,就實現(xiàn)的讀寫數(shù)據(jù)的函數(shù)封裝。

當用戶想往磁盤中寫入數(shù)據(jù)的時候只需要調(diào)用這些函數(shù)接口就行了。

然而這些函數(shù)都是針對最底層的數(shù)據(jù)存儲操作,不利于計算機的操作性能提高,所以,有人就在這層函數(shù)的基礎(chǔ)上再次進行封裝,把性能更加好,更加優(yōu)化的讀寫數(shù)據(jù)函數(shù)封裝到C語言的標準庫中。

在標準庫中的讀寫數(shù)據(jù)函數(shù),例如fwrite和fputs等等。它們不是每次寫入一個字節(jié)數(shù)據(jù)就往物理磁盤中寫入數(shù)據(jù),而是利用函數(shù)在內(nèi)存中開辟出一個固定大小的字節(jié)緩沖池,通過這個緩沖池,來實現(xiàn)數(shù)據(jù)的讀與寫。

(3)C語言中的數(shù)據(jù)緩沖池

C語言的所有讀寫函數(shù),都會使用到數(shù)據(jù)緩沖池,無論是讀數(shù)據(jù)操作,還是寫數(shù)據(jù)操作,都會把數(shù)據(jù)臨時存儲到這里。

寫數(shù)據(jù)

當我們使用C語言往文件中寫入一個字節(jié)的數(shù)據(jù)的時候,會經(jīng)歷一下幾個步驟:

  • 使用函數(shù)往目標文件中寫入一個字節(jié)的數(shù)據(jù)。
  • 數(shù)據(jù)被存儲在內(nèi)存的數(shù)據(jù)緩沖池中。
  • 關(guān)閉要寫入的文件。
  • 底層函數(shù)把緩沖池中的數(shù)據(jù)寫入磁盤中。

從上面的步驟中可以看出我們的函數(shù)在執(zhí)行到寫入數(shù)據(jù)的操作的時候,數(shù)據(jù)并沒有真正的寫入到磁盤中,而是等到寫入文件的操作結(jié)束的時候,才把數(shù)據(jù)緩沖池中的數(shù)據(jù)寫入磁盤中。

同樣的我們使用C語言讀一個字節(jié)數(shù)據(jù)的時候,同樣會經(jīng)歷一下步驟:

  • 打開要讀的文件。
  • 底層函數(shù)從磁盤中讀取滿整個緩沖池的數(shù)據(jù)。
  • 關(guān)閉要讀的文件。
  • 從緩沖池中讀取要讀取的字節(jié)數(shù),剩余沒用的數(shù)據(jù)不讀。

緩沖池工作原理

當知道我們的所有讀寫操作都要進入緩沖池時,我們同樣要知道緩沖池的工作原理。

  • 緩沖池有一定固定的大小
  • 緩沖池在進行讀數(shù)據(jù)的操作時,如果要讀取的數(shù)據(jù)字節(jié)小于緩沖池的大小,緩沖池會從磁盤中讀取滿整個緩沖池的數(shù)據(jù),所以當每次讀取的字節(jié)數(shù)過小,讀取次數(shù)過多的時候,會減少訪問實際磁盤的磁盤,增加程序運行的性能。
  • 緩沖池的刷新,每刷新一次都會進行與實際物理內(nèi)存的交互。

當緩沖池滿了或者目標操作文件關(guān)閉的時候,緩沖池會自動刷新,寫數(shù)據(jù)時,緩沖池的數(shù)據(jù)會進入物理磁盤;讀數(shù)據(jù)時,緩沖池的數(shù)據(jù)會數(shù)據(jù)固定字節(jié)的數(shù)據(jù)進入輸出終端。

總而言之,緩沖池僅僅是用戶與物理磁盤之間數(shù)據(jù)交戶的一個緩沖而已,不用想的太深奧。

三、使用函數(shù)刷新緩沖池

fflush函數(shù):

函數(shù)作用:

刷新緩沖池

函數(shù)定義:

int fflush(FILE *P);

參數(shù) 返回值:

  • P:目標操作文件
  • 返回值:如果成功,該函數(shù)返回零值。如果發(fā)生錯誤,則返回 EOF 。

使用示例:

現(xiàn)有空文件a.txt

利用標準輸入數(shù)據(jù),在文件沒有關(guān)閉的時候,查看文件內(nèi)是否有寫入的數(shù)據(jù)。

#include <stdio.h>
#include <string.h>
void write_file()
{
    FILE *p = fopen("a.txt", "w");
    char temp[100] = { 0 };
    while(1)
    {
        fgets(temp, sizeof(temp), stdin);
        if(strcmp(temp, "exit\n") == 0)
            break;
        fprintf(p, "%s", temp);
    }
    fclose(p);
}
int main()
{
    write_file();
    return 0;
}

運行結(jié)果:

輸入中

[文件]$ gcc -o a fflush.c
[文件]$ a
hello

查看文件a.txt

可以看到文件為空,輸入的文件現(xiàn)在正存儲在緩沖池中。

輸入exit退出輸入,查看文件a

[文件]$ cat a.txt
hello

文件關(guān)閉,緩沖池中的數(shù)據(jù)寫入磁盤。

現(xiàn)在我們創(chuàng)建一個函數(shù)使每輸入一次都寫入一次磁盤:

#include <stdio.h>
#include <string.h>
void write_file()
{
    FILE *p = fopen("a.txt", "w");
    char temp[100] = { 0 };
    while(1)
    {
        fgets(temp, sizeof(temp), stdin);
        if(strcmp(temp, "exit\n") == 0)
            break;
        fprintf(p, "%s", temp);
        fflush(p);
    }
    fclose(p);
}
int main()
{
    write_file();
    return 0;
}

運行結(jié)果:

輸入中,查看a.txt

[文件]$ gcc -o a fflush.c
[文件]$ a
hello

再開啟另一個終端查看文件 a.txt 狀態(tài):

[文件]$ cat a.txt
hello

輸入結(jié)束,查看a.txt

[文件]$ a
hello
exit
[文件]$ cat a.txt
hello
[文件]$ 

可以看到使用fflush函數(shù)把緩沖池中的數(shù)據(jù)寫入了磁盤。

四、總結(jié)

當我們在往磁盤中錄入重要的非常重要的數(shù)據(jù)的時候,一定要使用fflush不斷的刷新緩沖池,因為數(shù)據(jù)非常重要;但我們輸入不重要的數(shù)據(jù)是一定要盡量減少使用fflush函數(shù)的次數(shù),因為那樣會讓程序變得緩慢。

到此這篇關(guān)于C語言實現(xiàn)文件讀寫操作的幾種常用方法的文章就介紹到這了,更多相關(guān)C語言 文件讀寫操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中的函數(shù)返回值問題

    C++中的函數(shù)返回值問題

    這篇文章主要介紹了C++中的函數(shù)返回值問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 詳細對比C語言中的chmod()函數(shù)和fchmod()函數(shù)

    詳細對比C語言中的chmod()函數(shù)和fchmod()函數(shù)

    這篇文章主要介紹了C語言中的chmod()函數(shù)和fchmod()函數(shù)的詳細對比,兩個都是用于修改文件權(quán)限但是請注意實際使用上的差異,需要的朋友可以參考下
    2015-09-09
  • C++ 情懷游戲掃雷的實現(xiàn)流程詳解

    C++ 情懷游戲掃雷的實現(xiàn)流程詳解

    掃雷是電腦上很經(jīng)典很經(jīng)典的傳統(tǒng)老游戲,從小編第一次摸到計算機開始就玩過掃雷,雖然當時并不理解玩法原理,但終是第一次玩電腦游戲,下面來從掃雷的前世今生講起
    2021-11-11
  • C++中兩種字符串定義方式和區(qū)別介紹

    C++中兩種字符串定義方式和區(qū)別介紹

    大家好,本篇文章主要講的是C++中兩種字符串定義方式和區(qū)別介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C++中事件機制的簡潔實現(xiàn)及需要放棄的特性

    C++中事件機制的簡潔實現(xiàn)及需要放棄的特性

    事件模型是被廣泛使用的好東西,但是C++標準庫里沒有現(xiàn)成的,現(xiàn)在VC11可以用在XP下了,那么就痛快的拿起C++11提供的先進設(shè)施組合出一個輕便的實現(xiàn)吧感興趣的朋友可以了解下,或許對你有所幫助
    2013-02-02
  • 利用C++制作人生模擬器游戲的示例代碼

    利用C++制作人生模擬器游戲的示例代碼

    這篇文章主要為大家詳細介紹了如何利用C++制作一個當下很火的人生模擬器游戲,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-05-05
  • C語言數(shù)組超詳細講解下篇掃雷

    C語言數(shù)組超詳細講解下篇掃雷

    數(shù)組是一組有序的數(shù)據(jù)的集合,本篇將帶你結(jié)合數(shù)組來實現(xiàn)掃雷小游戲,上手實練更快的能夠掌握數(shù)組使用,感興趣的朋友來看看吧
    2022-04-04
  • 將?C++?類型屬性暴露給?QML

    將?C++?類型屬性暴露給?QML

    這篇文章主要介紹了將?C++?類型屬性暴露給?QML,?QML?是一種基于?JavaScript?的聲明式語言。在?Qt5中,QML有了長足進步,并且同?C++?并列成為?Qt?的首選編程語言下面一起進入文章學(xué)習(xí)?QML的條件下也看看如何將將?C++?類型屬性暴露給?QML,需要的朋友可以參考一下
    2021-12-12
  • C++ LeetCode1832題解判斷句子是否為全字母句

    C++ LeetCode1832題解判斷句子是否為全字母句

    這篇文章主要為大家介紹了C++ LeetCode1832題解判斷句子是否為全字母句示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • c/c++靜態(tài)庫之間相互調(diào)用的實戰(zhàn)案例

    c/c++靜態(tài)庫之間相互調(diào)用的實戰(zhàn)案例

    C++調(diào)用C的函數(shù)比較簡單,直接使用extern "C" {}告訴編譯器用C的規(guī)則去編譯C代碼就可以了,下面這篇文章主要給大家介紹了關(guān)于c/c++靜態(tài)庫之間相互調(diào)用的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08

最新評論

壤塘县| 淳化县| 兰州市| 大城县| 新营市| 白银市| 麻栗坡县| 镇远县| 许昌市| 天祝| 岳普湖县| 聂拉木县| 汉源县| 大埔县| 静安区| 江永县| 定边县| 东辽县| 隆昌县| 托克逊县| 太湖县| 梁山县| 察哈| 临邑县| 哈密市| 惠安县| 华宁县| 滦南县| 台南县| 元朗区| 天津市| 镇沅| 香港| 沭阳县| 黄石市| 金门县| 普陀区| 玛纳斯县| 旬邑县| 防城港市| 金乡县|