021-C語言文件操作

C語言文件操作

文章目錄

  • C語言文件操作
    • 1. 文件的概念
    • 2. 二進制文件和文本文件
    • 3. 文件的打開和關閉
      • 3.1 流和標準流
        • 3.1.1 流
        • 3.1.2 標準流
      • 3.2 文件指針
      • 3.3 文件的打開和關閉
    • 4. 文件的順序讀寫
      • 4.1 順序讀寫函數
      • 4.2 對比兩組函數
        • 4.2.1 scanf/fscanf/sscanf
        • 4.2.2 printf/fprintf/sprintf
    • 5. 文件的隨機讀寫
      • 5.1 fseek
      • 5.2 ftell
      • 6.3 rewind
    • 6. 文件讀取結束的判定
      • 6.1 被錯誤使用的feof
      • 6.2 判斷讀取結束
    • 7. 文件緩沖區

1. 文件的概念

  • 文件的作用:

    文件是用來存儲數據的,在之前寫的代碼中,只要我們對出程序,之前的數據就不復存在了,如果想要將數據保存到電腦上,就需要使用文件。

  • 文件的分類:程序文件、數據文件(從文件功能的角度來分類)

    • 程序文件:

      程序文件包括源程序文件(.c),目標文件(Windows下為.obj),可執行程序(Windows下為.exe)

    • 數據文件:

      內容不一定是程序,而是程序運行時讀寫的數據,比如程序允許需要從中讀取數據的文件,或者輸出內容的文件。

    • 文件標識:

      一個文件一定要有一個唯一的文件標識,以便識別和使用,文件標識分為三個部分:文件路徑+文件名主干+文件后綴,例如:C:\code\test.c,為了方便起見,文件標識常被稱為文件名

2. 二進制文件和文本文件

根據數據的組織形式,數據文件被稱為文本文件二進制文件

數據在內存中以二進制的形式存儲,如果不加轉換的輸出到外存,就是二進制文件。

如果要求外層加上ASCII碼的形式存儲,則需要在存儲前進行轉換。以ASCII字符的形式存儲的文件就是文本文件。

存儲的方式:字符一律以ASCII碼形式存儲,數值型數據既可以使用ASCII碼形式存儲,也可以使用二進制形式存儲。

如果有一個整數10000,如果以ASCII碼的形式輸出到磁盤,則磁盤中占用5個字節(每一個字符一個字節),而二進制形式輸出,則在磁盤上只占4個字節。

在這里插入圖片描述

3. 文件的打開和關閉

3.1 流和標準流

3.1.1 流

我們程序的數據需要輸出到各種外部設備,也需要從外部設備獲取數據,不同大外部設備的輸入輸出操作各不相同,為了方便程序員對各種設備進行方便的錯做,我們抽象出了流的概念。可以把流理解為一條流淌著字符的河流。

C程序針對文件、畫面、鍵盤等的數據輸入輸出都是對流進行操作的。

一般情況下,我們想要向流里寫數據,或者從流中讀取數據,都是要打開流,然后操作。

3.1.2 標準流

我們發現,我們之前的程序中,向鍵盤輸入數據,向屏幕上輸出數據,并沒有打開流。

那是因為C語言程序在啟動的時候默認打開了3個流:

  • stdin - 標準輸入流,大多數情況的環境中從鍵盤輸入。
  • stdout - 標準輸出流,大多數情況的環境中輸出至顯示屏。
  • stderr - 標準錯誤流,大多數情況的環境中輸出至顯示屏。

因為默認打開了這三個流,我們使用的scanf、printf等函數就可以直接進行輸入輸出操作。

stdinstdoutstderr這三個文件的類型是:FILE*,通常稱為文件指針。

C語言中就是通過FILE*的文件指針來維護流的各種操作的。

3.2 文件指針

緩沖文件系統中,關鍵的概念是文件類型指針,簡稱文件指針

每個被使用的文件都在內存中開辟了一個相應的文件信息區,用來存放文件的相關信息(如文件的名字,文件狀態,及文件當前的位置等)。這些信息是保存在一個結構體變量中的。該結構體類型是由系統聲明的,取名為FILE

下面是VS2013編譯環境中提供的stdio.h頭文件中的文件類型聲明。

struct _iobuf {char *_ptr;int _cnt;char *_base;int _flag;int _file;int _charbuf;int _bufsiz;char *_tmpfname;
};
typedef struct _iobuf FILE;

不同的C編譯器的FILE類型包含的內容不完全相同,但是大同小異(VS2022環境下的FILE類型和上面的似乎就不太一樣)。

每當打開一個文件的時候,系統回根據文件的情況自動創建一個FILE結構的變量,并填充其中的信息,使用者不必關心細節。

一般都是通過一個FILE的指針來維護這個FILE結構的變量,這樣使用起來更加方便。

創建FILE*指針變量:

FILE* fp;

pf是一個指向FILE類型數據的指針變量。可以使某個pf指向某個文件的文件信息區(是一個結構體變量)。通過該文件信息區中的信息就能夠訪問該文件。也就是說,通過文件指針變量能夠間接找到與它關聯的文件

在這里插入圖片描述

3.3 文件的打開和關閉

文件在讀寫之前應該要先打開文件,在使用結束后應該關閉文件

在編寫程序的時候,在打開文件的同時,都會返回應該FILE*的指針變量指向該文件,也相當于建立了指針和文件的關系。

ANSIC規定使用fopen函數來打開文件,fclose函數來關閉文件。

FILE * fopen ( const char * filename, const char * mode );int fclose ( FILE * stream );
  • filename:需要打開的文件名。
  • stream:需要關閉的文件的文件指針。
  • mode:文件的打開模式,如下表。
文件使用方式含義如果指定文件不存在
“r”(只讀)打開一個已經存在的文本文件,只進行讀取數據出錯
“w”(只寫)打開一個文本文件,如果文件存在,清空文件中原來的內容,只進行寫入數據建立新的文件
“a”(追加)打開一個文本文件,向文本文件末尾添加數據建立新的文件
“rb”(只讀)打開一個二進制文件,只進行讀取數據出錯
“wb”(只寫)打開一個二進制文件,如果文件存在,清空文件中原來的內容,只進行寫入數據建立新的文件
“ab”(追加)打開一個文本文件,向文本文件末尾添加數據建立新的文件
“r+”(讀寫)打開一個文本文件,進行讀寫操作出錯
“w+”(讀寫)打開一個文本文件,如果文件存在,清空文件中原來的內容,進行讀寫操作建立新的文件
“a+”(讀寫)打開一個文本文件,在文件末尾進行讀寫操作建立新的文件
“rb+”(讀寫)打開一個二進制文件,進行讀寫操作出錯
“wb+”(讀寫)打開一個二進制文件,如果文件存在,清空文件中原來的內容,進行讀寫操作建立新的文件
“ab+”(讀寫)打開一個二進制文件,在文件末尾進行讀寫操作建立新的文件
#include <stdio.h>int main()
{// 打開文件FILE* pf = fopen("test.txt", "w");// 關閉文件if (pf != NULL)fclose(pf);return 0;
}

4. 文件的順序讀寫

4.1 順序讀寫函數

函數名功能適用于
fgetc字符輸入函數所有輸入流
fputc字符輸出函數所有輸出流
fgets文本行輸入函數所有輸入流
fputs文本行輸出函數所有輸出流
fscanf格式化輸入函數所有輸入流
fprintf格式化輸出函數所有輸出流
fread二進制輸入函數文件
fwrite二進制輸出函數文件

上面的適用于所有輸入流一般指適用于標準輸出流和其他輸出流(如文件輸入流),所有輸出流一般指的是標準輸出流和其他輸出流(如文件輸出流)

4.2 對比兩組函數

4.2.1 scanf/fscanf/sscanf
int scanf ( const char * format, ... );
int fscanf ( FILE * stream, const char * format, ... );
int sscanf ( const char * s, const char * format, ...);
  • scanf:這個函數我們前面使用的很多,作用就是從標準輸入流獲取(一般是鍵盤)數據。
  • fscanf:從我們指定的流中獲取數據,比如從某文件中獲取數據,第一個參數傳遞文件指針即可,其他參數與scanf基本一致。
  • sscanf:從s字符串中獲取數據,第一個參數傳遞字符串指針,其他參數與scanf基本一致。

上面三個函數的返回值:讀取數據成功時,返回讀取成功的總項數,讀取數據失敗時,返回EOF。

4.2.2 printf/fprintf/sprintf
int printf ( const char * format, ... );
int fprintf ( FILE * stream, const char * format, ... );
int sprintf ( char * str, const char * format, ... );
  • printf:這個函數在前面使用過很多次,作用就是將指定內容輸出到標準輸出流中(一般是屏幕)。
  • fprintf:將數據輸出到指定的流中,比如輸出到某文件,第一個參數傳遞文件指針即可,其他參數與printf基本一致。
  • sprintf:將數據輸出到指定字符串中(寫入到字符串中),第一個參數傳遞指定的字符串指針,其他參數與printf基本一致。

上面三個函數的返回值:輸出成功時,則返回輸出的總字符數,輸出失敗時,則返回一個負數。

5. 文件的隨機讀寫

5.1 fseek

重新設置文件位置指示器。

文件位置指示器類似于我們的鼠標光標,當打開文件時,文件位置指示器位于文件的開頭。

int fseek ( FILE * stream, long int offset, int origin );
  • stream:文件指針
  • offset:偏移量,決定將文件指示器移動至相對于origin位置多少偏移量的位置,正數在表向右移,負數代表向左移。
  • origin:移動文件指針的相對位置。
    • SEEK_SET:文件開頭位置。
    • SEEK_CUR:文件指示器的當前位置。
    • SEEK_END:文件結尾位置。

注:庫實現可以不真正支持 SEEK_END (因此,使用它的代碼沒有真正的標準可移植性)。

#include <stdio.h>int main()
{FILE* pFile;pFile = fopen("example.txt", "wb");fputs("This is an apple.", pFile);fseek(pFile, 9, SEEK_SET);fputs(" sam", pFile);fclose(pFile);return 0;
}

在這里插入圖片描述

5.2 ftell

long int ftell ( FILE * stream );

stream:文件指針。

返回文件指針相對于起始位置的偏移量。

#include <stdio.h>
int main()
{FILE* pFile;long size;pFile = fopen("myfile.txt", "rb");if (pFile == NULL)perror("Error opening file");else{fseek(pFile, 0, SEEK_END); // non-portablesize = ftell(pFile);fclose(pFile);printf("Size of myfile.txt: %ld bytes.\n", size);}return 0;
}

在這里插入圖片描述

在這里插入圖片描述

6.3 rewind

void rewind ( FILE * stream );

讓文件指針的位置回到文件的起始位置。

#include <stdio.h>
int main()
{int n;FILE* pFile;char buffer[27];pFile = fopen("myfile.txt", "w+");for (n = 'A'; n <= 'Z'; n++)fputc(n, pFile);rewind(pFile);fread(buffer, 1, 26, pFile);fclose(pFile);buffer[26] = '\0';printf(buffer);return 0;
}

在這里插入圖片描述

6. 文件讀取結束的判定

6.1 被錯誤使用的feof

int feof ( FILE * stream );

檢查文件結束指示符。

當一個文件位置指示器讀取數據嘗試讀取到文件末尾或之后時,文件結束指示符會被設置。

當結束指示符被設置時,feof將返回非零值,否則返回0;

當未到文件末尾時,讀取就已經結束,這種情況文件結束指示符不會被設置,feof將返回0。

所以我們不能用feof判斷讀取是否結束。

6.2 判斷讀取結束

  1. 文本文件讀取是否結束可以判斷讀取函數的返回值是否為EOF(如fgetc)或NULL(如fgets)。
  2. 二進制文件的讀取結束判斷,判斷返回值是否小于實際要讀的個數,如使用fread判斷返回值是否小于實際要讀的個數。

7. 文件緩沖區

ANSIC標準采用緩沖文件系統處理數據文件,所謂文件緩沖系統就是指系統自動在內存中為程序中每個正在使用的文件開辟一塊文件緩沖區。從內存向磁盤輸出數據會先送到內存中的緩沖區,裝滿緩沖區后才一起送到磁盤上。如果從磁盤向計算機讀入數據,則從磁盤文件讀取數據輸入到內存緩沖區(充滿緩沖區),然后再沖緩沖區逐個地將數據送到程序數據區(程序變量等)。緩沖區的大小根據C編譯系統決定。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903015.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903015.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903015.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何使用@KafkaListener實現從nacos中動態獲取監聽的topic

1、簡介 對于經常需要變更kafka主題的場景&#xff0c;為了實現動態監聽topic的功能&#xff0c;可以使用以下方式。 2、使用步驟 2.1、添加依賴 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactI…

《TCP/IP詳解 卷1:協議》之第七、八章:Ping Traceroute

目錄 一、ICMP回顯請求和回顯應答 1、ICMP回顯請求 2、ICMP回顯應答 二、ARP高速緩存 三、IP記錄路由選項&#xff08;Record Route&#xff0c;RR&#xff09; 1、記錄路由選項的工作過程 2、RR 選項的 IP 頭部格式 2.1、RR 請求 2.2、RR響應 四、ping 的去返路徑 五…

30天通過軟考高項-第四天

30天通過軟考高項-第四天 任務&#xff1a;項目進度管理 思維導圖閱讀 知識點集錦閱讀 知識點記憶 章節習題練習 知識點練習 手寫回憶ITTO 聽一遍喜馬拉雅關于范圍的內容 進度管理-背 1. 過程定義 龜腚排池至控 規劃進度管理&#xff1a;為了規劃、編制、管理…

根據JSON動態生成表單表格

根據JSON動態生成表單表格 一. 子組件 DynamicFormTable.vue1,根據JSON數據動態生成表單表格,支持表單驗證JS部分1.1,props數據1.2,表單數據和數據監聽1.3,自動驗證1.4,表單驗證1.5,獲取表單數據1.6,事件處理1.7,暴露方法給父組件2,HTML部分二,父組件1, 模擬數據2,…

【趙渝強老師】快速上手TiDB數據庫

從TiDBv4.0起&#xff0c;提供了包管理工具TiUP&#xff0c;負責管理TiDB、PD、TiKV等組件。用戶只需通過TiUP命令即可運行這些組件&#xff0c;顯著降低了管理難度。TiUP程序只包含少數幾個命令&#xff0c;用來下載、更新、卸載組件。TiUP通過各種組件來擴展其功能。組件是一…

springboot入門-DTO數據傳輸層

在 Spring Boot 應用中&#xff0c;DTO&#xff08;Data Transfer Object&#xff0c;數據傳輸對象&#xff09; 是專門用于在不同層&#xff08;如 Controller 層、Service 層、外部系統&#xff09;之間傳輸數據的對象。它的核心目的是解耦數據模型和業務邏輯&#xff0c;避免…

安裝docker,在docker上安裝mysql,docker上安裝nginx

目錄 一.安裝docker 1.1查看Linux版本的命令這里推薦兩種&#xff1a; 1.2查看內核版本有三種方式&#xff1a; 2.安裝 2.1 如果之前安裝了docker&#xff0c;先刪除舊版本的doker 2.2 安裝需要的軟件包&#xff0c;yum-util提供yum-config-manager功能&#xff0c;另外兩…

Android killPackageProcessesLSP 源碼分析

該方法用于終止指定包名/用戶ID/應用ID下符合條件的應用進程&#xff0c;涉及多進程管理、資源凍結、進程清理及優先級更新等操作。核心流程分為進程篩選、資源凍結、進程終止與資源恢復三個階段。 /*** 從已排序的進程列表中&#xff0c;提取從指定起始索引 startIdx 開始的連…

openAICEO山姆奧特曼未來預測雄文之三個觀察

《三個觀察》 山姆奧特曼 這篇文章主要講的是關于AGI&#xff08;人工通用智能&#xff09;的未來發展及其對社會的影響&#xff0c;用大白話總結如下&#xff1a; 核心觀點&#xff1a; AGI是什么&#xff1f; AGI是一種能像人類一樣解決各種復雜問題的智能系統&#xff0c;比…

部署yolo到k230教程

訓練&#xff1a;K230 借助 AICube部署AI 視覺模型 YOLO等教程_嘉楠 ai cube多標簽分類-CSDN博客K230模型訓練ai cube報錯生成部署文件異常_aicube部署模型顯示生成部署文件異常-CSDN博客 部署&#xff1a; # 導入必要的庫和模塊 import os import ujson # 超快的JS…

Flask 應用封裝成 Docker 服務的完整技術指南

一、實現原理 容器化核心邏輯 Docker 通過將應用代碼、運行環境和依賴項打包成鏡像&#xff0c;實現環境一致性。Flask 應用容器化需包含&#xff1a; Python 基礎運行環境項目代碼及依賴庫&#xff08;requirements.txt&#xff09;WSGI服務器&#xff08;如 Gunicorn&#xf…

windows上的 Vmware Workstation 環境搭建

本文的視頻版本&#xff1a;https://www.bilibili.com/video/BV1JhLRzyESh Vmware Workstation 是一款跨平臺的桌面級虛擬化軟件&#xff0c;可以使用 Vmware 創建虛擬機&#xff0c;我們一般使用 Linux 虛擬機&#xff08;目前主流的 Linux 發行版是 Ubuntu&#xff09;&…

Linux下終端命令行安裝常見字體示例

一、準備工作&#xff1a; 準備好要安裝的字體文件&#xff0c;如宋體、微軟雅黑&#xff08;simsun.ttc、msyh.ttc)。進入字體路徑&#xff1a; /usr/share/fonts&#xff0c;使用root權限&#xff0c;新建一個目錄shell_fonts。 二、命令行安裝字體&#xff1a; 將要安裝…

CentOS中在線安裝Docker(超詳細)

1&#xff09;檢查安裝docker的基本要求&#xff1a; 64位CPU架構的計算機&#xff0c;目前不支持32為CPU架構的計算機 系統的Linux內核版本為3.10及以上 開啟CGroups和namespace功能 2&#xff09;使用命令查看當前系統的內核版本 [rootlocalhost ~]# uname -r 3.10.0-862…

武漢昊衡科技OLI光纖微裂紋檢測儀:高密度光器件的精準守護者

隨著AI技術應用越來越廣&#xff0c;算力需求激增&#xff0c;光通信系統正加速向小型化、高密度、多通道方向演進。硅光芯片、高速光模塊等核心器件內部的光纖通道數量成倍增加&#xff0c;波導結構愈發精細&#xff0c;傳統檢測手段因分辨率不足、效率低下&#xff0c;難以精…

Java數據結構——Stack

Stack 棧的概念和使用棧的概念棧的使用 棧的應用出棧元素序列有效的括號棧的壓入、彈出序列逆波蘭表達式最小棧 棧的概念和使用 棧的概念 棧(Stack)&#xff1a;一種特殊的線性表&#xff0c;只允許再棧的一端進行插入和刪除元素&#xff0c;這一端點被稱為棧頂&#xff0c;另…

神經網絡與計算機視覺

2016 年,隨著 AlphaGo 在圍棋比賽中擊敗李世石,“人工智能”、“神經網絡”、“深度 學習”等字眼便越來越多的出現在大眾眼前,智能化好像成為一種不可逆轉的趨勢,帶給大家新奇感的同時也帶來了一絲憂懼:在不遠的未來,機器是否真的擁有思維和情感?《終結者》中天網大戰人…

VS2019 與gitcode團隊管理

1、安裝git 點擊下一步安裝即可 2、vs2019連接gitcode 然后更改本地的代碼添加文件等都可以進行遠程同步操作了

Python類和對象四(十三)

魔法方法&#xff1a; 按位運算 按位于運算 只要相同才是1 或運算&#xff1a; 只要某個位是1結果就是1 、 按位非 將結果取反 按位異或&#xff1a; 左移和右移運算符&#xff1a; 右移兩位 右移動n位&#xff0c;就是除以2的n次方 左移兩位&#xff1a; 左移n位就是乘…

如何設置極狐GitLab 議題截止日?

極狐GitLab 是 GitLab 在中國的發行版&#xff0c;關于中文參考文檔和資料有&#xff1a; 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 截止日期 (BASIC ALL) 可以在議題中使用截止日期&#xff0c;來跟蹤截止日期并確保功能按時交付。用戶至少需要報告者權限才…