網站首頁 編程語言 正文
1.什么是文件
我們先從基本概念入手,內存中存放的數據在計算機關機后就會消失。要長久保存數據,就要使用硬盤、光盤、U 盤等設備。為了便于數據的管理和檢索,引入了“文件”的概念。一篇文章、一段視頻、一個可執行程序,都可以被保存為一個文件,并賦予一個文件名。操作系統以文件為單位管理磁盤中的數據。
1.1程序文件
包括源程序文件(后綴為.c),目標文件(windows環境后綴為.obj),可執行程序(windows環境后綴為.exe)。
1.2數據文件
文件的內容不一定是程序,而是程序運行時讀寫的數據,比如程序運行需要從中讀取數據的文件,或者輸出內容的文件。
1.3文件名
一個文件要有一個唯一的文件標識,以便用戶識別和引用。
文件名包含3部分:文件路徑+文件名主干+文件后綴
例如: c:\code\test.txt
為了方便起見,文件標識常被稱為文件名
2.為什么使用文件
當我們想把數據在計算機上保留下來,只有自己主動清理的時候才不復存在時我們加需要將數據保存在磁盤上,就需要用文件的方式。
這篇文章主要討論數據文件
3.文件的打開和關閉
3.1文件指針
當我們想要打開一個文件是就會用用到文件指針。每個被使用的文件都在內存中開辟了一個相應的文件信息區,用來存放文件的相關信息(如文件的名字,文件狀態及文件當前的位置等)。這些信息是保存在一個結構體變量中的。該結構體類型是有系統聲明的,取名FILE。每當打開一個文件的時候,系統會根據文件的情況自動創建一個FILE結構的變量,并填充其中的信息,使用者不必關心細節。
一般都是通過一個FILE的指針來維護這個FILE結構的變量,這樣使用起來更加方便
FILE* pf//文件指針變量
定義pf是一個指向FILE類型數據的指針變量??梢允筽f指向某個文件的文件信息區(是一個結構體變量)。通過該文件信息區中的信息就能夠訪問該文件。也就是說,通過文件指針變量能夠找到與它關聯的文件。
3.2文件的打開和關閉
在文件的打開和關閉中我們需要用到兩個庫函數,fopen和fclose,因為在ANSIC 規定使用fopen函數來打開文件,fclose來關閉文件。當我們打開文件過后我們需要判斷一下時候打開文件成功才能進行下一步操作,等操作完畢后關閉文件,在使用fopen的時候需注意的是我們需要兩個參數,一個是文件名,一個是打開方式。打開方式圖標和代碼演示如下。
文件使用方式 | 含義 | 如果指定文件不存在 |
---|---|---|
"r"(只讀) | 為了輸入數據,打開一個已經存在的文本文件? | 出錯 |
"w"(只寫) | 為了輸出數據,打開一個文本文件 | 建立一個新的文件 |
"a"(追加) | 向文本文件尾添加數據 | 建立一個新的文件 |
"rb"(只讀) | 為了輸入數據,打開一個二進制文件 | 出錯 |
"wb"(只寫) | 為了輸出數據,打開一個二進制文件 | 建立一個新文件 |
"ab"(追加) | 向一個二進制文件尾添加數據 | 出錯 |
"r+"(讀寫) | 為了讀和寫,打開一個文本文件 | 出錯 |
"w+"(讀寫) | 為了讀和寫,建立一個新的文件 | 建立一個新的文件 |
"a+"(讀寫) | 打開一個文件,在文件尾進行讀寫 | 建立一個新的文件 |
"rb+"(讀寫) | 為了讀和寫打開一個二進制文件 | 出錯 |
"wb+"(讀寫) | 為了讀和寫,新建一個新的二進制文件 | 建立一個新的文件 |
"ab+"(讀寫) | 打開一個二進制文件,在文件尾進行讀和寫 | 建立一個新的文件 |
#include<stdio.h>
int main()
{
//打開文件
FILE* pf = fopen("test.txt","w")//w代表write,表示寫文件
//判斷文件是否打開
if(pf == NULL)
{
perror("fopen");//打開失敗返回錯誤信息
return;
}
//寫文件
//關閉文件
fclose(pf);
pf=NULL;
return 0;
}
4.文件的順序讀寫
在對文件進行一些順序讀寫的時候我們需要用到一些功能函數如下:
功能 | 函數名 | 適用于 |
---|---|---|
字符輸入函數 | fgetc | 所有輸入流 |
字符輸出函數 | fputc | 所有輸出流 |
文本行輸入函數 | fgets | 所有輸入流 |
文本行輸出函數 | fputs | 所有輸出流 |
格式化輸入函數 | fscanf | 所有輸入流 |
格式化輸出函數 | fprintf | 所有輸出流 |
二進制輸入 | fread | 文件 |
二進制輸出 | fwrite | 文件 |
什么是流
流是個抽象的概念,是對輸入輸出設備的抽象。設備可以是文件,網絡,內存等。流具有方向性,至于是輸入流還是輸出流則是一個相對的概念,一般以程序為參考,如果數據的流向是程序至設備,我們成為輸出流,反之我們稱為輸入流。可以將流想象成一個“水流管道”,水流就在這管道中形成了,自然就出現了方向的概念。
相對于編譯器來說 輸入:將文件中的數據拿出來 輸出:將數據放入文件中
這里用代碼給大家演示一下輸入與輸出:
int main()
{
//打開文件
FILE* pf = fopen("test.txt", "w");//寫
if (pf == NULL)
{
perror("fopen");
return;
}
//寫如abcd
fputc('a', pf);
fputc('b', pf);
fputc('c', pf);
fputc('d', pf);
//關閉文件
fclose(pf);
pf = NULL;
return 0;
}
那么現在文件里已經有數據了(“abcde”),我們想把數據拿出來呢?我們就要用到輸入。代碼演示如下:
int main()
{
FILE* pf = fopen("test.txt", "r");//讀
if (pf == NULL)
{
perror("fopen");
return;
}
//拿出字符a
int ch = fgetc(pf);
printf("%c\n", ch);
fclose(pf);
pf = NULL;
return 0;
}
當我們讀了字符'a'過后,偏移量從0變到1,這就叫順序讀寫。
這里我們對比一組函數:
scanf - 格式化的輸入函數
printf - 格式化的輸出函數
fscanf - 針對所有輸入流的格式化的輸入函數
fprintf - 針對所有輸出流的格式化輸出函數
sscanf - 把一個字符串轉換成格式化的數據
sprintf - 把一個格式化的數據轉換成字符串
5.文件的隨機讀寫
5.1fseek
fseek是根據文件指針位置和偏移量來定位文件指針的函數
int fseek ( FILE * stream, long int offset, int origin );
// offset - 偏移量
// origin表示如下:
//1.SEEK_CUR - 文件指針當前的位置
//2.SEEK_END - 文件末尾的位置
//3.SEEK_SET - 文件開始的位置
我們采用上面的列子,在文件中輸入了"abcd",我們想找到 'c' 該怎么做呢代碼演示:
int main()
{
//打開文件
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return;
}
//寫文件
fseek(pf, 2, SEEK_CUR);//c相對于文件當前位置的的偏移量為2
int ch = fgetc(pf);
printf("%c\n", ch);
//關閉文件
fclose(pf);
pf = NULL;
return 0;
}
5.2ftell
返回文件相對于起始位置的偏移量,返回的數據類型為long
long int ftell ( FILE * stream );
用法很簡單,用上面的例子來給大家講解,我們首先將使用fseek函數將偏移量改到2,隨后用fgetc函數后,偏移量向后移,目前偏移量應該是3.
int main()
{
//打開文件
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return;
}
//寫文件
fseek(pf, 2, SEEK_CUR);//c相對于文件當前位置的的偏移量為2
int ch = fgetc(pf);
printf("%c\n", ch);
//重置偏移量
long pos = ftell(pf);//3
printf("%d\n",pos);
//關閉文件
fclose(pf);
pf = NULL;
return 0;
}
5.3rewind
讓文件指針的位置回到文件的起始位置
void rewind ( FILE * stream );
int main()
{
//打開文件
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return;
}
//寫文件
fseek(pf, 2, SEEK_CUR);//c相對于文件當前位置的的偏移量為2
int ch = fgetc(pf);
printf("%c\n", ch);
long pos = ftell(pf);
printf("%d\n", pos);
//重置偏移量
rewind(pf);
pos = ftell(pf);
printf("%d\n", pos);
//關閉文件
fclose(pf);
pf = NULL;
return 0;
}
原文鏈接:https://blog.csdn.net/m0_56653788/article/details/124078561
相關推薦
- 2022-08-21 Android自定義view貝塞爾曲線_Android
- 2022-05-20 docker內的容器如何與宿主機共享IP的方法_docker
- 2022-02-22 Linux系統下根目錄擴容介紹_Linux
- 2022-08-27 C#實現截圖幫助類_C#教程
- 2023-08-30 Git忽略已經提交過一次文件Git忽略文件
- 2022-11-30 React中常見的TypeScript定義實戰教程_React
- 2022-12-02 docker進階教程之dockerfile優化鏡像大小_docker
- 2023-09-17 el-table嵌入輸入框下拉框按鈕等等
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支