網站首頁 編程語言 正文
前言
二進制文件讀寫兩個重要的函數 , fread 和 fwrite , fread 用于讀取文件 , fwrite 用于寫出文件 ;
fread / fwrite 函數 既可以操作 二進制文件 , 又可以操作 文本文件 ;
getc / putc 函數 , fscanf / fprintf 函數 , fgets / fgets 函數 , 只能用于操作 文本文件 ;
一、fread 函數
fread 函數作用 : 從文件中讀取若干字節數據到內存緩沖區中 ;
fread 函數原型 :
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
void *buffer 參數 : 將文件中的二進制數據讀取到該緩沖區中 ;
size_t size 參數 : 讀取的 基本單元 字節大小 , 單位是字節 , 一般是 buffer 緩沖的單位大小 ;
- 如果 buffer 緩沖區是 char 數組 , 則該參數的值是 sizeof(char) ;
- 如果 buffer 緩沖區是 int 數組 , 則該參數的值是 sizeof(int) ;
size_t count 參數 : 讀取的 基本單元 個數 ;
FILE *stream 參數 : 文件指針 ;
size_t 返回值 : 實際從文件中讀取的 基本單元 個數 ; 讀取的字節數是 基本單元數 * 基本單元字節大小 ;
代碼示例 : 一次性讀滿整個緩沖區 ;
#include <stdio.h> int main() { // 使用 "rb" 讀取二進制方式打開文件 FILE *p = fopen("D:\\a.txt", "rb"); // 用于接收讀取數據的緩沖區 char buffer[1024] = {0}; // buffer : 將文件讀取到內存的位置 // sizeof(char) : 讀取的基本單元字節長度 // sizeof(buffer) : 讀取的基本單元個數, // 讀取字節個數是 sizeof(buffer) * sizeof(char) // p : 文件指針 fread(buffer, sizeof(char), sizeof(buffer), p); // 打印讀取的內容 printf("buffer = %s\n", buffer); printf("Main End\n"); return 0; }
執行結果 :
二、緩沖區受限的情況 ( 循環讀取文件 | feof 函數判定文件讀取完畢 )
假設緩沖區很小 , 文件很大 , 則需要循環讀取文件數據 ;
使用 feof(p)
判定文件是否讀取完畢 , 如果返回 true 說明文件沒有讀取完畢 , 返回 false , 說明文件讀取完畢 ;
代碼示例 :
#include <stdio.h> int main() { // 使用 "rb" 讀取二進制方式打開文件 FILE *p = fopen("D:\\a.txt", "rb"); // 用于接收讀取數據的緩沖區 char buffer[4] = {0}; while(!feof(p)){ memset(buffer, 0, sizeof(buffer)); // buffer : 將文件讀取到內存的位置 // sizeof(char) : 讀取的基本單元字節長度 // sizeof(buffer) : 讀取的基本單元個數, // 讀取字節個數是 sizeof(buffer) * sizeof(char) // p : 文件指針 fread(buffer, sizeof(char), sizeof(buffer), p); // 打印讀取的內容 printf("buffer = %s\n", buffer); } printf("Main End\n"); return 0; }
執行結果 : 讀取之后出現亂碼 , 這是由于每次讀取 10 10 10 字節 , 但是字符串必須要以 ‘\0’ 進行結尾 , 如果沒有 ‘\0’ 則會一直讀取直到出現 ‘\0’ 字符串結尾位置 ;
三、處理亂碼問題
為了避免上述打印出現亂碼的情況 , char buffer[4] = {0};
準備了 4 4 4 字節緩沖區 , 每次只使用其中的 3 3 3 個字節 , 這就能保證最后一個字節必定是 ‘\0’ , 打印時就不會出現亂碼 ;
代碼示例 :
#include <stdio.h> int main() { // 使用 "rb" 讀取二進制方式打開文件 FILE *p = fopen("D:\\a.txt", "rb"); // 用于接收讀取數據的緩沖區 char buffer[4] = {0}; while(!feof(p)){ memset(buffer, 0, sizeof(buffer)); // buffer : 將文件讀取到內存的位置 // sizeof(char) : 讀取的基本單元字節長度 // sizeof(buffer) : 讀取的基本單元個數, // 讀取字節個數是 sizeof(buffer) * sizeof(char) // p : 文件指針 fread(buffer, sizeof(char), sizeof(buffer) - 1, p); // 打印讀取的內容 printf("buffer = %s\n", buffer); } printf("Main End\n"); return 0; }
執行結果 : 每次從文件中讀取 緩沖區字節數 - 1 個字節 , 則能完整的將文本打印出來 ;
四、記錄讀取的字節個數
fread 函數返回值表示讀取到的 基本單元 的個數 , 如果設置了 1KB 的緩沖區 , 但是文件中只有 5 字節 , 則 fread 的返回值就是實際讀取到的數據個數 ;
代碼示例 :
#include <stdio.h> int main() { // 使用 "rb" 讀取二進制方式打開文件 FILE *p = fopen("D:\\a.txt", "rb"); // 用于接收讀取數據的緩沖區 char buffer[1024] = {0}; // buffer : 將文件讀取到內存的位置 // sizeof(char) : 讀取的基本單元字節長度 // sizeof(buffer) : 讀取的基本單元個數, // 讀取字節個數是 sizeof(buffer) * sizeof(char) // p : 文件指針 // 返回值 : fread 函數返回值表示讀取到的 基本單元 的個數 size_t count = fread(buffer, sizeof(char), sizeof(buffer) - 1, p); // 打印讀取的內容 printf("buffer = %s , read count = %u\n", buffer, count); printf("Main End\n"); return 0; }
執行結果 :
五、讀取到 0 字節的情況
如果 基本單元 大小 4 4 4 字節 , 文件中只有 3 3 3 字節數據 , 則使用 fread 函數讀取文件 , 緩沖區設置 1KB , 則實際讀取到的基本單元個數是 0 0 0 ;
代碼示例 :
#include <stdio.h> int main() { // 使用 "rb" 讀取二進制方式打開文件 FILE *p = fopen("D:\\a.txt", "rb"); // 用于接收讀取數據的緩沖區 char buffer[1024] = {0}; // buffer : 將文件讀取到內存的位置 // sizeof(char) : 讀取的基本單元字節長度 // sizeof(buffer) : 讀取的基本單元個數, // 讀取字節個數是 sizeof(buffer) * sizeof(char) // p : 文件指針 // 返回值 : fread 函數返回值表示讀取到的 基本單元 的個數 size_t count = fread(buffer, sizeof(int), sizeof(buffer) - 1, p); // 打印讀取的內容 printf("buffer = %s , read count = %u\n", buffer, count); printf("Main End\n"); return 0; }
執行結果 :
六、讀取完畢的情況
如果文件已經讀取完畢 , 不關閉文件 , 再次調用 fread 函數繼續讀取 , 則讀取到的 基本單元 個數是 0 0 0 ;
使用 feof(p)
判定文件是否讀取完畢 , 如果返回 true 說明文件沒有讀取完畢 , 返回 false , 說明文件讀取完畢 ;
代碼示例 :
#include <stdio.h> int main() { // 使用 "rb" 讀取二進制方式打開文件 FILE *p = fopen("D:\\a.txt", "rb"); // 用于接收讀取數據的緩沖區 char buffer[1024] = {0}; // buffer : 將文件讀取到內存的位置 // sizeof(char) : 讀取的基本單元字節長度 // sizeof(buffer) : 讀取的基本單元個數, // 讀取字節個數是 sizeof(buffer) * sizeof(char) // p : 文件指針 // 返回值 : fread 函數返回值表示讀取到的 基本單元 的個數 size_t count = fread(buffer, sizeof(char), sizeof(buffer) - 1, p); // 打印第一次讀取的內容 printf("First fread : buffer = %s , read count = %u\n", buffer, count); count = fread(buffer, sizeof(int), sizeof(buffer) - 1, p); // 打印第二次讀取的內容 printf("Second fread : buffer = %s , read count = %u\n", buffer, count); printf("Main End\n"); return 0; }
執行結果 :
七、讀取文本文件 “\n” 與 讀取二進制文件 “\r\n” 區別
以下區別只在 Windows 系統存在 , 在 Linux / Unix 中讀取文本數據與二進制數據沒有區別 ;
使用 ‘rb’ 方式打開文件 , 讀取二進制文件 , 然后調用 fread 函數讀取文件 ,
#include <stdio.h> int main() { // 使用 "rb" 讀取二進制方式打開文件 FILE *p = fopen("D:\\a.txt", "rb"); // 用于接收讀取數據的緩沖區 char buffer[1024] = {0}; // buffer : 將文件讀取到內存的位置 // sizeof(char) : 讀取的基本單元字節長度 // sizeof(buffer) : 讀取的基本單元個數, // 讀取字節個數是 sizeof(buffer) * sizeof(char) // p : 文件指針 // 返回值 : fread 函數返回值表示讀取到的 基本單元 的個數 size_t count = fread(buffer, sizeof(char), sizeof(buffer) - 1, p); // 打印第一次讀取的內容 printf("fread : buffer = %s , read count = %u\n", buffer, count); // 逐個字節打印讀取出數據的 ASCII 碼 int i = 0; for(i = 0; i < count; i ++){ printf("buffer[%d] = %x\n", i, buffer[i]); } printf("Main End\n"); return 0; }
執行結果 : 第 2 2 2 個索引讀取出來的值是 0xd 對應 ‘\r’ , 第 3 3 3 個值是 0xa 對應 ‘\n’ ;
注意 : 最后兩個字節是空行對應的 “\r\n” ;
fread : buffer = ab cd , read count = 8 buffer[0] = 61 buffer[1] = 62 buffer[2] = d buffer[3] = a buffer[4] = 63 buffer[5] = 64 buffer[6] = d buffer[7] = a Main End
使用 ‘r’ 方式打開文件 , 讀取文本文件 , 然后調用 fread 函數讀取文件 ,
#include <stdio.h> int main() { // 使用 "rb" 讀取二進制方式打開文件 FILE *p = fopen("D:\\a.txt", "r"); // 用于接收讀取數據的緩沖區 char buffer[1024] = {0}; // buffer : 將文件讀取到內存的位置 // sizeof(char) : 讀取的基本單元字節長度 // sizeof(buffer) : 讀取的基本單元個數, // 讀取字節個數是 sizeof(buffer) * sizeof(char) // p : 文件指針 // 返回值 : fread 函數返回值表示讀取到的 基本單元 的個數 size_t count = fread(buffer, sizeof(char), sizeof(buffer) - 1, p); // 打印第一次讀取的內容 printf("fread : buffer = %s , read count = %u\n", buffer, count); // 逐個字節打印讀取出數據的 ASCII 碼 int i = 0; for(i = 0; i < count; i ++){ printf("buffer[%d] = %x\n", i, buffer[i]); } printf("Main End\n"); return 0; }
執行結果 : 第 2 2 2 個索引讀取出來的值是 0xa 對應 ‘\n’ ;
最后的空行只有一個 ‘\n’ ;
fread : buffer = ab cd , read count = 6 buffer[0] = 61 buffer[1] = 62 buffer[2] = a buffer[3] = 63 buffer[4] = 64 buffer[5] = a Main End
總結?
原文鏈接:https://blog.csdn.net/shulianghan/article/details/117338844
相關推薦
- 2022-05-10 SpringBoot端口已占用解決:配置端口號
- 2023-02-12 完美解決Redis在雙擊redis-server.exe出現閃退問題_Redis
- 2022-01-03 antd獲取表單的所有數據
- 2022-10-29 【npm 報錯 gyp info it worked if it ends with ok 大概率是
- 2022-12-25 C++?Boost?Random隨機函數詳解_C 語言
- 2023-04-17 Python屬性私有化詳解_python
- 2023-03-16 redis如何取hash的值_Redis
- 2022-09-26 ASP.NET?MVC打印表格并實現部分視圖表格打印_實用技巧
- 最近更新
-
- 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同步修改后的遠程分支