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

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

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

一 、文件讀寫的常用函數(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) 讀寫二進(jìn)制文件

讀二進(jìn)制文件: 使用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;
}

寫二進(jìn)制文件: 使用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)與硬件儲(chǔ)存

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

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

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

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

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

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

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

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

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

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

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

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

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

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

寫數(shù)據(jù)

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

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

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

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

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

緩沖池工作原理

當(dāng)知道我們的所有讀寫操作都要進(jìn)入緩沖池時(shí),我們同樣要知道緩沖池的工作原理。

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

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

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

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

fflush函數(shù):

函數(shù)作用:

刷新緩沖池

函數(shù)定義:

int fflush(FILE *P);

參數(shù) 返回值:

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

使用示例:

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

利用標(biāo)準(zhǔn)輸入數(shù)據(jù),在文件沒有關(guān)閉的時(shí)候,查看文件內(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;
}

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

輸入中

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

查看文件a.txt

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

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

[文件]$ cat a.txt
hello

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

現(xiàn)在我們創(chuàng)建一個(gè)函數(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;
}

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

輸入中,查看a.txt

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

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

[文件]$ cat a.txt
hello

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

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

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

四、總結(jié)

當(dāng)我們?cè)谕疟P中錄入重要的非常重要的數(shù)據(jù)的時(shí)候,一定要使用fflush不斷的刷新緩沖池,因?yàn)閿?shù)據(jù)非常重要;但我們輸入不重要的數(shù)據(jù)是一定要盡量減少使用fflush函數(shù)的次數(shù),因?yàn)槟菢訒?huì)讓程序變得緩慢。

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

相關(guān)文章

  • c語言線程終止練習(xí)示例

    c語言線程終止練習(xí)示例

    這篇文章主要介紹了c語言線程終止練習(xí)示例,需要的朋友可以參考下
    2014-04-04
  • VC獲取當(dāng)前路徑及程序名的實(shí)現(xiàn)代碼

    VC獲取當(dāng)前路徑及程序名的實(shí)現(xiàn)代碼

    VC上或取當(dāng)前路徑有多種方法,最常用的是使用 GetCurrentDirectory和GetModuleFileName函數(shù),個(gè)中都有諸多注意事項(xiàng),特別總結(jié)一下
    2016-11-11
  • C語言模擬實(shí)現(xiàn)strstr函數(shù)的示例代碼

    C語言模擬實(shí)現(xiàn)strstr函數(shù)的示例代碼

    strstr是C語言中的函數(shù),作用是返回字符串中首次出現(xiàn)子串的地址。本文將用C語言模擬實(shí)現(xiàn)strstr函數(shù),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-07-07
  • C++ STL入門教程(3) deque雙向隊(duì)列使用方法

    C++ STL入門教程(3) deque雙向隊(duì)列使用方法

    這篇文章主要為大家詳細(xì)介紹了C++ STL入門教程第三篇,deque雙向隊(duì)列的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • C語言實(shí)現(xiàn)手寫Map(全功能)的示例代碼

    C語言實(shí)現(xiàn)手寫Map(全功能)的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C語言實(shí)現(xiàn)手寫Map(全功能),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語言有一定幫助,需要的可以參考一下
    2022-08-08
  • C語言結(jié)構(gòu)體內(nèi)存對(duì)齊問題小結(jié)

    C語言結(jié)構(gòu)體內(nèi)存對(duì)齊問題小結(jié)

    本文主要講解了C語言中結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則、計(jì)算方法以及影響因素,包括對(duì)齊規(guī)則的四個(gè)要點(diǎn)、內(nèi)存對(duì)齊的原因、如何修改默認(rèn)對(duì)齊數(shù)以及結(jié)構(gòu)體傳參時(shí)的注意事項(xiàng),此外,還介紹了結(jié)構(gòu)體位段的概念、內(nèi)存分配和使用注意事項(xiàng),感興趣的朋友一起看看吧
    2025-02-02
  • C++實(shí)現(xiàn)俄羅斯方塊游戲

    C++實(shí)現(xiàn)俄羅斯方塊游戲

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)俄羅斯方塊游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • C++17中std::string_view的使用

    C++17中std::string_view的使用

    std::string_view是C++17標(biāo)準(zhǔn)庫中的一種新類型,它提供了對(duì)一個(gè)字符序列的非擁有式視圖,本文主要介紹了C++17中std::string_view的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • c文件匯編后函數(shù)參數(shù)傳遞的不同之處

    c文件匯編后函數(shù)參數(shù)傳遞的不同之處

    在w7 32位系統(tǒng)下把c文件匯編后,確實(shí)與mac后的差異很大??刹粌H僅是寄存器eax與rax的區(qū)別。我想說的是函數(shù)參數(shù)傳遞的不同
    2013-11-11
  • C語言詳細(xì)分析講解內(nèi)存管理malloc realloc free calloc函數(shù)的使用

    C語言詳細(xì)分析講解內(nèi)存管理malloc realloc free calloc函數(shù)的使用

    C語言內(nèi)存管理相關(guān)的函數(shù)主要有realloc、calloc、malloc、free等,下面這篇文章主要給大家介紹了關(guān)于C語言內(nèi)存管理realloc、calloc、malloc、free函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2022-05-05

最新評(píng)論