C語言之文件操作

2020-09-04 我臉上有bug

前些時候,我們學習的C語言程序都是由輸入輸出和算法組成的控制臺程序。我們在終端上來輸入我們提供的數據,然後程序也會通過終端來告訴我們最終運行的結果。



但是,可能有的同學已經觀察到了,我們日常使用的別人開發的程序,大多數都是通過文件來提供數據的。比如一個Excel的報表,程序可以直接來分析裡面的數據。再比如,一個TXT格式的電子書,程序可以直接分析有多少字、多少個章節,甚至還可以生成出一個目錄來。

擁有這樣能力的程序,是不是感覺功能強大了許多?這就要用到我們今天要講到的內容——「文件操作」

關於文件

在我們比較熟悉的Windows系統下,文件類型的區分是用「擴展名」來進行的。但其實擴展名並不是指「文件格式」,它只是一個「門牌號」而已。至於它到底對不對,那系統就不知道了。可能有很多的新手,在遇到格式的問題的時候,會認為直接更改擴展名,就能實現格式轉換。不瞞你們說,我小時候也有過這種想法。但是後來發現,不行。舉個例子,現在有一個 MP3 的文件,要轉成 AAC。這兩個文件從編碼上來講,就是不一樣的。MP3 只能用 MP3 的方式去讀取,AAC 只能用 AAC 的方式去讀取。如果你把擴展名直接改成 AAC,那麼系統就被你騙了,就會用 AAC 的方式去讀取實際還是 MP3 的文件,當然是不行了。

不同的擴展名,就對應了不同的讀取方式。「EXE」 就代表 Windows 系統下的可執行二進位文件,「TXT」是純文本文件,等等。

在 Linux 和 Unix 作業系統下,文件的定義就寬泛多了。不光軟體,硬體也可以叫文件。也就是說,硬體實際上也是當做文件的方式來處理的。

在C語言中,文件一般分為兩種,一種是二進位文件,就是我們編譯出來的那個東西,我們是看不懂的;另一種是文本文件,也就是我們常說的原始碼。

打開和關閉文件

我們要對一個文件進行操作,首先我們需要把文件打開,然後才能讀或者寫。對文件操作完成後,我們還要將文件關閉。

C語言中的打開文件使用fopen函數,通式如下:

fopen(&34;, &34;)

如果打開文件成功,則會返回一個FILE結構的指針,通過這個指針,我們就可以對這個文件進行操作;如果打開文件失敗,則會返回NULL。

下面是所有的模式:


前面幾個都好理解,只是最後一個,為啥要區分一個二進位出來呢?

不加「b」的情況下,就是以文本的形式來打開。因為在不同的作業系統中,換行符是不同的。Unix系統用\n,MacOS用\r,而Windows用的是\r\n,那麼在文本模式下打開,C語言會根據系統環境的不同,來轉化換行符。而在二進位的模式下,就不會進行任何的轉換。

當你對文件操作完畢後,一定要記得把文件用fclose()函數來關閉。其實我們在打開文件後的所有操作,實際上都被記錄到了緩存裡,只有執行了關閉後,我們的更改才會生效。如果關閉成功,則函數會返回0;失敗的話,就會返回EOF。關閉成功後,我們創建的文件指針就會失效。

//Example 01//學習交流群:782648055include <stdlib.h>int main(void){ FILE* f; int chr; if ((f = fopen(&34;, &34;)) == NULL) { printf(&34;); exit(EXIT_FAILURE); } while ((chr = getc(f)) != EOF) { putchar(chr); } fclose(f); return 0;}

//file1.txt中的內容C programming makes me happy!

//Consequence 01C programming makes me happy!

順序讀寫文件

打開了文件之後,就可以進行我們的操作了。

讀寫單個字符

讀取單個字符,我們可以用fgetc和getc這兩個來實現。它們的作用,就是讀取一個字符,然後將光標移動到下一個位置。

include <stdio.h>...int fputc(int c, FILE* stream);int putc(int c, FILE* stream);

第一個參數是你要寫入的字符,第二個是你要寫入的文件流。

讀寫整個字符串

這裡就要用到fgets和fputs兩個函數了。

39;\0&include <stdio.h>include <time.h>int main(void){    FILE* fp;    struct  tm* p;    time_t t;        time(&t);    p = localtime(&t);    //寫入日期到文件    if ((fp = fopen(&34;, &34;)) == NULL)    {        printf(&34;);        exit(EXIT_FAILURE);    }    fprintf(fp, &34;, 1900 + p -> tm_year, 1 + p -> tm_mon, p -> tm_mday);    fclose(fp);    //讀取文件日期,輸出到終端    int year, month, day;    if ((fp = fopen(&34;, &34;)) == NULL)    {        printf(&34;);        exit(EXIT_FAILURE);    }    fscanf(fp, &34;, &year, &month, &day);    printf(&34;, year, month, day);    fclose(fp);    return 0;}

//date.txt中的內容2020-6-15

//Consequence 022020-6-15

二進位讀寫

我們用fopen函數可以用二進位的方式來打開一個文件,但實際上我們要用二進位的方式來讀寫,還得用相應的函數才行。

C語言提供了fread和fwrite兩個函數來實現二進位的讀取和寫入。

include <stdio.h>...long ftell(FILE* stream);

如果將一個文件看成一個數組,那麼這個函數返回的就是這個數組的下標。

//Example 01include <stdlib.h>int main(void){    FILE* fp;    if ((fp = fopen(&34;, &34;)) == NULL)    {        printf(&34;);        exit(EXIT_FAILURE);    }    printf(&34;, ftell(fp));    fputc(&39;, fp);    printf(&34;, ftell(fp));    fputs(&34;, fp);    printf(&34;, ftell(fp));    fclose(fp);        return 0;}

//data.txt中的內容TechZone

//Consequence 010110

如果你想將光標快速移動到文件頭,可以用rewind函數來實現。

...rewind(fp);fputs(&34;, fp);fclose(fp);...

//data.txt中的內容Helloone

可以看到,它會覆蓋我們前面的數據。

有的同學可能會說了,你這不還是沒解決問題嗎?

好的,那就來解決下問題吧。C語言給我們提供了一個函數fseek,這個函數可以直接把光標跳轉到我們想要的位置。

34;打開文件失敗!\n&34;出錯了!\n&include <errno.h>...printf(&34;, errno);...

舉個例子:

打開文件失敗:2

但是這個錯誤代碼不是所有人都知道它的含義。所以C語言又提供了一個函數perror,它可以直接用文字來提示我們錯誤的地方。

34;打開文件失敗,原因是");...

結果是這樣的:

打開文件失敗,原因是:No such file or directory

中間的冒號是自動加上的。

或許以後在你的開發生涯中,用的最多的不是C語言,但這門語言對你帶來的提升,那是不可忽視的。最後,祝各位學有所成!

關注我,帶你遨遊代碼的世界

獲取完整視頻教程,可以關注B站:https://www.bilibili.com/video/BV1QE411y7v4

相關焦點

  • 乾貨|C語言文件的基本操作!
    本文轉載自【微信公眾號:手機電腦雙黑客,ID:heikestudio】經微信公眾號授權轉載,如需轉載與原文作者聯繫c語言對文件的操作主要分為:按字符操作,按行操作,按內存塊操作主要的函數:fopen():FILE * fopen(_In_z_ const char * _Filename, _In_z_ const char
  • c語言文件操作整理
    推薦《c陷阱與缺陷》FILE *fp;fp = fopen(file, "r+");編程者也許認為,程序一旦執行上述操作完畢,就可以自由地進行讀取和寫入的操作了。遺憾的是,事實總難遂人所願,為了保持與過去不能同時進行讀寫操作的程序的向下兼容性,一個輸入操作不能隨後直接緊跟輸出操作,反之亦然。
  • C語言文件操作
    C 語言把文件看作是一個字符(字節)的序列,即由一個一個字符(字節)的數據順序組成。根據數據的組織形式,可分為 ASCⅡ 文件和二進位文件。文件的操作包括:文件的打開、文件的關閉、文件的讀寫操作、文件狀態檢查以及文件的定位等。 1 文件的打開 1.1 函數原型 1.2 功能說明 按照 mode 規定的方式,打開由 pname指定的文件。
  • C開發實戰-文件操作
    /表示,Visual Studio2019 本地Windows調試器運行時源文件file_open_close.c的當前目錄是D:\workspace\c\ittimelinedotnet\vs2019\c-core\c-core-advanced,打開方式可以是如下幾種方式r或rb 以只讀方式打開一個文本文件(不創建文件,若文件不存在則報錯)w或wb 以寫方式打開文件
  • 現代程式語言起點,C語言之環境搭建
    但也就是因為它有指針,可以直接進行靠近硬體的操作,所以帶來很多不安全的因素二、C語言的環境搭建1、作業系統說明:推薦使用Unix系統,比如類Unix系統的Linux系統中的CentOs、Ubantu系統,或者使用Mac。
  • C語言文本文件操作
    >1、打開成功,返回有效地址2、打開失敗,返回NULL3、「w」,如果文件不存在,新建一個123.txt,如果存在,清除裡面的內容4、「r」,如果文件不存在,打開失敗5、「a」,如果文件不存在,新建,如果存在,光標移動到最後面二、讀寫文件1、按字符讀寫fgetc()、fputc
  • C語言 技能提升 系列文章(九)文件定位
    文件,顧名思義,就是存在某個文件夾下的文件。對應於物理設備的話,可能是HDD/SSD/Flash等等。但是為了能讓我們來讀寫他的內容,作業系統會將文件內容讀取到內存中,然後我們就可以像操作其他內存數據一樣操作文件了。但是,由於文件的特殊性,我們不能像操作數組一樣,操作文件緩存。不過,C語言本身卻給我們提供了方便的庫函數API,基本上和操作數組一類的緩存,一樣方便了。
  • C語言項目中.h和.c文件的關係和概念
    ,那時的人們寫了很多的.c(.cpp)文件,漸漸地,人們發現在很多.c(.cpp)文件中的聲明語句就是相同的。 但他們卻不得不一個字一個字地重複地將這些內容敲入每個.c(.cpp)文件。但更為恐怖的是,當其中一個聲明有變更時,就需要檢查所有的.c(.cpp)文件。 於是人們將重複的部分提取出來,放在一個新文件裡,然後在需要的.c(.cpp)文件中敲入#include XXXX這樣的語句。
  • C/C++學習日記:C語言編譯器gcc命令如何操作步驟
    前言:C語言的應用範圍廣泛,具備很強的數據處理能力,不僅僅是在軟體開發上,而且各類科研都需要用到C語言,適於編寫系統軟體,三維在 UNIX 系統中,C 語言編譯器稱為 cc。實際上,gcc 能夠編譯三種語言:C、C++ 和 Object C(C 語言的一種面向對象擴展)。利用 gcc 命令可同時編譯並連接 C 和 C++ 源程序,一般來說,C 編譯器通過源文件的後綴名來判斷是 C 程序還是 C++ 程序。
  • C語言頭文件被include後都發生了什麼?為何不能在頭文件定義變量
    C語言的#include語法頭文件通常與C語言的#include 語法配合使用,意為「將頭文件內容包含進來」,例如在 t.c 文件裡寫下這段C語言代碼:C語言代碼編譯器在編譯這段C語言代碼之前,會有一個「預處理」的過程,在此過程中,stdio.h 裡的內容被展開到 t.c 文件裡。
  • 物聯網應用開發之C語言介紹
    當前階段,在編程領域中,C語言的運用非常之多,它兼顧了高級語言的彙編語言的優點,相較於其它程式語言具有較大優勢。計算機系統設計以及應用程式編寫是C語言應用的兩大領域。同時,C語言的普適較強,在許多計算機作業系統中都能夠得到適用,且效率顯著。
  • 製作和使用自定義C語言庫文件
    庫文件的生成  為敘述方便,請在C盤根目錄中新建一目錄,並將其命名為libtest。以下將C:\libtest簡稱為工作目錄。  在ICCAVRIDE環境中新建兩個文件,分別命名為 GetMax.c 和 GetMax.h,並保存至工作目錄中。
  • 物聯網開發筆記——嵌入式開發之Linux系統中C語言變量
    第二節物聯網開發筆記——嵌入式開發之Linux系統中文件和目錄相關命令第三節物聯網開發筆記——嵌入式開發之Linux系統Vi編輯器的使用第四節物聯網開發筆記——嵌入式開發之Linux系統中C程序的編譯與調試第五節物聯網開發筆記——嵌入式開發之Linux系統中C語言數據類型第六節物聯網開發筆記——嵌入式開發之Linux系統中C語言常量
  • C語言頭文件路徑剖析
    在一個軟體項目中,如果需要在一個文件中包含另一個頭文件時,一般有兩種包含方式:include 「module.h」如果你引用的頭文件是標準庫的頭文件或官方路徑下的頭文件,一般使用尖括號 <> 包含;如果你使用的頭文件是自定義的或項目中的頭文件,一般使用雙引號 &34; 包含。
  • 跟光磊學C語言-C語言概述與開發環境搭建
    c-core新建源文件 helloworld.cC語言的源文件必須是以.c為擴展名,新建文件默認是文本文件,即.txt結尾的擴展名。(hellworld.c)終端定位源文件的快捷方式:在文件資源管理的源文件路徑(D:\workspace\c\core)輸入cmd就會自動彈出終端,終端當前所處的路徑就在源文件對應的目錄。
  • c語言程序設計自學教程
    如果您不甘落後,那麼請自製自控,自學c語言程序設計也是完全可能的。c語言十分依賴於計算機思維,而思維的培養不是一日之功,而是一個日積月累的過程一:準確把握語法語句概念1、編譯預處理不是C語言的一部分,不佔運行時間,不要加分號。C語言編譯的程序稱為源程序它以ASCII數值存放在文本文件中。
  • PIC單片機C語言程序設計(8)
    如此按提示操作下去,即可順利完成PICC8.05 編譯器的安裝(動手操作時,除圖25 中修改磁碟路徑外,都只需用滑鼠點擊各文件的按鈕(命令),如用滑鼠點擊NEXT 等,操作很簡單。即可用MPLAB IDE7.40 對PIC 單片機建立彙編語言或C 語言的源程序、創建項目(project)、對源程序進行彙編(使用彙編語言時)或編譯(使用C 語言時),彙編或編譯通過後,會生成目標碼。hex 文件。有了目標碼。hex 文件,就可對PIC 單片機編程(燒寫)和對源程序進行模擬調試了。
  • C語言程序設計教程
    導讀:C語言是一門通用的計算機程式語言,應用非常得廣泛,在計算機、單片機以及工業上都有的莫大的貢獻,今天我們來學習如何進行C語言程序設計。
  • 第六篇:C語言中結構體與文件操作相關知識點梳理
    前面總結過,C語言中的基本數據類型有四種,分別是整型、浮點型和字符型;後面又講到可以保存字符串的字符數組。但這遠遠不夠實際應用的需要。在C語言中結構體是對數據類型的無限擴展。程式設計師可以根據需要定義各種各樣的數據類型,即:結構體。問題二:數據無法永久保存前面我們編寫運行的所有C語言程序,或多或少都會輸入一些數據。
  • 加速程序開發 Python整合C語言模塊
    Python是一種用於快速開發軟體的程式語言,它的語法比較簡單,易於掌握,但存在執行速度慢的問題,並且在處理某些問題時存在不足,如對計算機硬體系統的訪問,對媒體文件的訪問等。而作為軟體開發的傳統程式語言C語言,卻能在這些問題上很好地彌補Python語言的不足。