網站首頁 編程語言 正文
1.文件讀寫
一個文件,無論它是文本文件還是二進制文件,都是代表了一系列的字節。C 語言不僅提供了訪問頂層的函數,也提供了底層(OS)調用來處理存儲設備上的文件。
1.1打開文件
我們可以使用 fopen( )
函數來創建一個新的文件或者打開一個已有的文件,這個調用會初始化類型 FILE 的一個對象,類型 FILE 包含了所有用來控制流的必要的信息。
下面是這個函數調用的原型:
FILE *fopen( const char * filename, const char * mode );
在這里,filename
是字符串,用來命名文件,訪問模式 mode
的值可以是下列值中的一個:
模式 | 描述 |
---|---|
r | 打開一個已有的文本文件,允許讀取文件。 |
w | 打開一個文本文件,允許寫入文件。如果文件不存在,則會創建一個新文件。在這里,您的程序會從文件的開頭寫入內容。 |
a | 打開一個文本文件,以追加模式寫入文件。如果文件不存在,則會創建一個新文件。在這里,您的程序會在已有的文件內容中追加內容。 |
r+ | 打開一個文本文件,允許讀寫文件。 |
w+ | 打開一個文本文件,允許讀寫文件。如果文件已存在,則文件會被截斷為零長度,如果文件不存在,則會創建一個新文件。 |
a+ | 打開一個文本文件,允許讀寫文件。如果文件不存在,則會創建一個新文件。讀取會從文件的開頭開始,寫入則只能是追加模式。 |
如果處理的是二進制文件,則需使用下面的訪問模式來取代上面的訪問模式:
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
1.2關閉文件
為了關閉文件,請使用 fclose( ) 函數。
函數的原型如下:
int fclose( FILE *fp );
如果成功關閉文件,fclose( )
函數返回零,如果關閉文件時發生錯誤,函數返回 EOF。這個函數實際上,會清空緩沖區中的數據,關閉文件,并釋放用于該文件的所有內存。EOF 是一個定義在頭文件 stdio.h
中的常量。
C 標準庫提供了各種函數來按字符或者以固定長度字符串的形式讀寫文件。
1.3讀取文件
下面是從文件讀取單個字符的最簡單的函數:
int fgetc( FILE * fp );
fgetc()
函數從 fp 所指向的輸入文件中讀取一個字符。返回值是讀取的字符,如果發生錯誤則返回 EOF。下面的函數允許您從流中讀取一個字符串:
char *fgets( char *buf, int n, FILE *fp );
函數 fgets()
從 fp 所指向的輸入流中讀取 n - 1 個字符。它會把讀取的字符串復制到緩沖區 buf,并在最后追加一個 null 字符來終止字符串。
如果這個函數在讀取最后一個字符之前就遇到一個換行符 '\n' 或文件的末尾 EOF,則只會返回讀取到的字符,包括換行符。您也可以使用 int fscanf(FILE *fp, const char *format, ...)
函數來從文件中讀取字符串,但是在遇到第一個空格字符時,它會停止讀取。
示例:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <Windows.h> //讀取文本文件 void main() { char path[] = "C:\Users\Administrator\Desktop\friend.txt"; //文本中語句為 hello world //打開 FILE *fp = fopen(path, "r"); if (fp == NULL) { printf("文件打開失敗..."); return; } //讀取 char buff[50];//緩沖 while (fgets(buff,50,fp)) { printf("%s", buff); } //關閉 fclose(fp); getchar(); }
結果輸出:
?hello world
1.4寫入文件
下面是把字符寫入到流中的最簡單的函數:
int fputc( int c, FILE *fp );
函數 fputc()
把參數 c 的字符值寫入到 fp 所指向的輸出流中。如果寫入成功,它會返回寫入的字符,如果發生錯誤,則會返回 EOF。
我們可以使用下面的函數來把一個以 null 結尾的字符串寫入到流中:
int fputs( const char *s, FILE *fp );
函數 fputs() 把字符串 s 寫入到 fp 所指向的輸出流中。如果寫入成功,它會返回一個非負值,如果發生錯誤,則會返回 EOF。您也可以使用 int fprintf(FILE *fp,const char *format, ...)
函數來寫把一個字符串寫入到文件中。
嘗試下面的實例:
//寫入文本文件 void main() { char *path = "C:\Users\Administrator\Desktop\test.txt"; //打開 FILE *fp = fopen(path, "w"); char *text = "今天天氣不錯\n出去玩吧!"; fputs(text,fp); //關閉 fclose(fp); getchar(); }
在test文本中輸出:
今天天氣不錯
出去玩吧!
注意:請確保您有可用的 /tmp 目錄,如果不存在該目錄,則需要在您的計算機上先創建該目錄。
1.5讀寫二進制I/O文件
計算機的文件存儲在物理上都是二進制,文本文件和二進制之分,其實是一個人為的邏輯之分。
C讀寫文本文件與二進制文件的差別僅僅體現在回車換行符:
- 1.寫文本時,每遇到一個'\n',會將其轉換成'\r\n'(回車換行)。
- 2.讀文本時,每遇到一個'\r\n',會將其轉換成'\n'。
- 3.但是讀寫二進制文件的時候并不會做以上轉換。
函數原型:
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
其中:
-
ptr
:指向保存結果的指針; -
size
:每個數據類型的大小; -
count
:數據的個數; -
stream
:文件指針
函數返回讀取數據的個數。
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
其中,ptr:指向保存數據的指針;size:每個數據類型的大小;count:數據的個數;stream:文件指針
函數返回寫入數據的個數。
下面是二進制文件讀寫的例子(圖片的復制):
void main() { char *read_path = "D:\BaiduNetdiskDownload\ndk\2016_08_08_C_聯合體_枚舉_IO\files\girl.png"; char *write_path = "D:\BaiduNetdiskDownload\ndk\2016_08_08_C_聯合體_枚舉_IO\files\girl_new.png"; //b字符表示操作二進制文件binary FILE *read_fp = fopen(read_path, "rb"); //寫的文件 FILE *write_fp = fopen(write_path,"wb"); //復制 int buff[50]; //緩沖區域 int len = 0;//每次讀到的數據長度 while ((len = fread(buff,sizeof(int), 50,read_fp))!=0) {//50 是寫的比較大的一個數 //將讀到的內容寫入新的文件 fwrite(buff, sizeof(int), len, write_fp); } fclose(read_fp); fclose(write_fp); getchar(); }
1.6獲取文件的大小
void main() { char *read_path = "D:\BaiduNetdiskDownload\ndk\2016_08_08_C_聯合體_枚舉_IO\files\girl.png"; FILE *fp = fopen(read_path, "r"); //重新定位文件指針 //SEEK_END文件末尾,0偏移量 fseek(fp, 0, SEEK_END); //返回當前的文件指針,相對于文件開頭的位移量 long filesize = ftell(fp); printf("%d\n", filesize); getchar(); }
1.7文本簡單加密、解密
void crypt(char normal_path[], char crypt_path[]) { //打開文件 FILE *normal_fp = fopen(normal_path, "r"); FILE *crypt_fp = fopen(crypt_path, "w"); //一次讀取一個字符 int ch; while ((ch = fgetc(normal_fp)) != EOF) { //End of File //寫入(異或運算) fputc(ch ^ 9, crypt_fp); } // 關閉 fclose(crypt_fp); fclose(normal_fp); } //解密 void decrypt(char crypt_path[],char decrypt_path[]) { //打開文件 FILE *normal_fp = fopen(crypt_path,"r"); FILE *crypt_fp = fopen(decrypt_path, "w"); //一次讀取一個字符 int ch; while ((ch = fgetc(normal_fp)) !=EOF)//End of File { //寫入(異或運算) fputc(ch ^ 9, crypt_fp); } //關閉 fclose(crypt_fp); fclose(normal_fp); } void main() { char *normal_path = "D:\userinfo.txt"; char *crypt_path = "D:\userinfo_crypt.txt"; char *decrypt_path = "D:\userinfo_decrypt.txt"; //加密文件 crypt(normal_path, crypt_path); //解密文件 decrypt(crypt_path, decrypt_path); getchar(); }
1.8二進制文件簡單加解密
void crypt(char normal_path[], char crypt_path[], char password[]) { //打開文件 FILE *normal_fp = fopen(normal_path, "rb"); FILE *crypt_fp = fopen(crypt_path, "wb"); //一次讀取一個字符 int ch; int i = 0; //循環使用密碼中的字母進行異或運算 int pwd_len = strlen(password); //密碼的長度 while ((ch = fgetc(normal_fp)) != EOF) { //End of File //寫入(異或運算) fputc(ch ^ password[i % pwd_len], crypt_fp); i++; } //關閉 fclose(crypt_fp); fclose(normal_fp); } //解密 void decrypt(char crypt_path[], char decrypt_path[], char password[]) { //打開文件 FILE *normal_fp = fopen(crypt_path, "rb"); FILE *crypt_fp = fopen(decrypt_path, "wb"); //一次讀取一個字符 int ch; int i = 0; //循環使用密碼中的字母進行異或運算 int pwd_len = strlen(password); //密碼的長度 while ((ch = fgetc(normal_fp)) != EOF) { //End of File //寫入(異或運算) fputc(ch ^ password[i % pwd_len], crypt_fp); i++; } //關閉 fclose(crypt_fp); fclose(normal_fp); } void main() { char *normal_path = "D:\girl.png"; char *crypt_path = "D:\girl_crypt.png"; char *decrypt_path = "D:\girl_decrypt.png"; //加密文件 crypt(normal_path, crypt_path, "123456"); //加密文件 decrypt(crypt_path, decrypt_path, "123456"); getchar(); }
一般騰訊、阿里等大公司的用戶關鍵數據是用C\C++(動態庫so反編譯很難)加密的。因為Java的加密方法反編譯比較容易破解。
原文鏈接:https://juejin.cn/post/7039205524952317959
相關推薦
- 2022-09-12 jQuery事件注冊的實現示范_jquery
- 2022-03-11 C++實操之內聯成員函數介紹_C 語言
- 2022-01-21 編程實現打印楊輝三角(要求使用一維數組處理)
- 2023-01-28 C#實現自定義單選和復選按鈕樣式_C#教程
- 2023-03-27 Android數據結構優化教程_Android
- 2022-09-09 C++中vector<vector<int>?>的基本使用方法_C 語言
- 2022-09-26 將Tomcat注冊為系統服務
- 2023-11-11 【LaTex】如何輸入英文字母的花體字?花體字最全總結
- 最近更新
-
- 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同步修改后的遠程分支