談到文件,先了解下什麼是文本文件和二進制文件的區别吧!
1、文本文件:存儲時是将字符的ASCII值存在磁盤中,取的時候将數值(ASCII)翻譯成對應的字符;
2、二進制文件:存取的都是二進制;
文件流指針:
當打開一個文件時,系統會返回一個結構體,這個結構體有對此文件操作的所有信息
調用fopen時(fopen的返回值: 如果成功返回FILE結構體地址,失敗返回NULL;
返回的文件流指針标識了打開的那個文件),系統返回這個結構體地址,比如如下所示:
FILE*P = fopen("test.txt");
說太多的東西不如代碼演示一遍,代碼如下所示:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
// 打開一個文件,成功則返回這個FLIE結構體地址,失敗則返回NULL;
FILE *fp = fopen("./test.txt", "w");
if (NULL == fp) {
perror(""); // 打印輸錯的信息
return;
}
fclose(fp); // 關閉文件
return 0;
}
以上代碼是在相對路徑下執行的,為了直接在vs中調試運行。注意:對于相對路徑相對的是工程文件。
設備文件:但啟動一個程序時,系統會打開三個設備文件,分别是:
1、stdin 标準輸入文件:
FILE *stdin = fopen(stdin,"r")
2、stdout 标準輸出文件:
FILE *stdout = fopen(stdout,"w")
3、stderr 标準錯誤文件:
FILE *stderr = fopen(stderr,"w")
1、fputc():
格式:
int fputc(int ch, FILE * stream);
/*
功能:将ch轉換為unsigned char後寫入stream指定的文件中
參數:
ch:需要寫入文件的字符
stream:文件指針
返回值:
成功:成功寫入文件的字符
失敗:返回-1
*/
作用:寫入一個字符到文件當中。
代碼演示如下所示:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
// 打開一個文件,成功則返回這個FLIE結構體地址,失敗則返回NULL;
FILE *fp = fopen("./test.txt", "w");
if (NULL == fp) {
perror(""); // 打印輸錯的信息
return;
}
char strBuf[] = "abcde";
int n = 0;
while (strBuf[n] != 0) {
fputc(strBuf[n], fp);
n ;
}
fclose(fp); // 關閉文件
return 0;
}
2、fgetc():
格式
int fgetc(FILE * stream);
/*
功能:從stream指定的文件中讀取一個字符
參數:
stream:文件指針
返回值:
成功:返回讀取到的字符
失敗:-1
*/
代碼演示如下所示:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
// 打開一個文件,成功則返回這個FLIE結構體地址,失敗則返回NULL;
FILE *fp = fopen("./test.txt", "r");
if (NULL == fp) {
perror(""); // 打印輸錯的信息
return;
}
char strBuf[128] = "";
int n = 0;
while ((strBuf[n ] = fgetc(fp)) != EOF);
printf("%s\n", strBuf);
fclose(fp); // 關閉文件
return 0;
}
在上面代碼提到了用“EOF”作為文件的結尾,也要提下 feof() 這個函數的使用方法。
為什麼要提到這個函數,主要是如果讀取文件不是純文本的時候,有像-1這種數字,那麼就不可以使用EOF(-1)作為文件的結尾,就需要用到foef()函數。
格式:
int feof(FILE * stream);
/*
功能:檢測是否讀取到了文件結尾。判斷的是最後一次“讀操作的内容”,不是當前位置内容(上一個内容)。
參數:
stream:文件指針
返回值:
非0值:已經到文件結尾
0:沒有到文件結尾
*/
用代碼形式演示如下所示:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
// 打開一個文件,成功則返回這個FLIE結構體地址,失敗則返回NULL;
FILE *fp = fopen("./test.txt", "r");
if (NULL == fp) {
perror(""); // 打印輸錯的信息
return;
}
char strBuf[128] = "";
int n = 0;
do {
strBuf[n ] = fgetc(fp);
} while (!feof(fp)); // 非0值讀到文件末尾,取反則為未讀到文件末尾
printf("%s\n", strBuf);
fclose(fp); // 關閉文件
return 0;
}
1、fgets(讀取字符串):
作用:從文件讀取字符串,fgets讀取中遇到\n結束;
格式:
char * fgets(char * str, int size, FILE * stream);
/*
功能:從stream指定的文件内讀入字符,保存到str所指定的内存空間,直到出現換行字符、讀到文件結尾或是已讀了size - 1個字符為止,最後會自動加上字符 '\0' 作為字符串結束。
參數:
str:字符串
size:指定最大讀取字符串的長度(size - 1)
stream:文件指針
返回值:
成功:成功讀取的字符串
讀到文件尾或出錯: NULL
*/
2、fputs(寫入字符串):
作用:向文件寫入字符串;
格式:
int fputs(const char * str, FILE * stream);
/*
功能:将str所指定的字符串寫入到stream指定的文件中,字符串結束符 '\0' 不寫入文件。
參數:
str:字符串
stream:文件指針
返回值:
成功:0
失敗:-1
*/
1、fprintf():
作用:組包函數,寫文件;
格式:
int fprintf(FILE * stream, const char * format, ...);
/*
功能:根據參數format字符串來轉換并格式化數據,然後将結果輸出到stream指定的文件中,指定出現字符串結束符 '\0' 為止。
參數:
stream:已經打開的文件
format:字符串格式,用法和printf()一樣
返回值:
成功:實際寫入文件的字符個數
失敗:-1
*/
2、fscanf():
作用:拆包函數(讀文件):
格式:
int fscanf(FILE * stream, const char * format, ...);
/*
功能:從stream指定的文件讀取字符串,并根據參數format字符串來轉換并格式化數據。
參數:
stream:已經打開的文件
format:字符串格式,用法和scanf()一樣
返回值:
成功:參數數目,成功轉換的值的個數
失敗: - 1
*/
1、fwrite()寫入函數:
格式:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
/*
功能:以數據塊的方式給文件寫入内容
參數:
ptr:準備寫入文件數據的地址
size: size_t 為 unsigned int類型,此參數指定寫入文件内容的塊數據大小
nmemb:寫入文件的塊數,寫入文件數據總大小為:size * nmemb
stream:已經打開的文件指針
返回值:
成功:實際成功寫入文件數據的塊數目,此值和 nmemb 相等
失敗:0
*/
需要注意的是:在第二個參數寫1,,返回值即是寫入的塊數也是寫入的字節數。
2、fread()讀取函數:
格式:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
/*
功能:以數據塊的方式從文件中讀取内容
參數:
ptr:存放讀取出來數據的内存空間
size: size_t 為 unsigned int類型,此參數指定讀取文件内容的塊數據大小
nmemb:讀取文件的塊數,讀取文件數據總大小為:size * nmemb
stream:已經打開的文件指針
返回值:
成功:實際成功讀取到内容的塊數,如果此值比nmemb小,但大于0,說明讀到文件的結尾。
失敗:0
*/
分别為三個函數:如下所示:
1、fseek():
作用:可以移動光标。
格式:
int fseek(FILE *stream, long offset, int whence);
/*
功能:移動文件流(文件光标)的讀寫位置。
參數:
stream:已經打開的文件指針
offset:根據whence來移動的位移數(偏移量),可以是正數,也可以負數,如果正數,則相對于whence往右移動,如果是負數,則相對于whence往左移動。如果向前移動的字節數超過了文件開頭則出錯返回,如果向後移動的字節數超過了文件末尾,再次寫入時将增大文件尺寸。
whence:其取值如下:
SEEK_SET:從文件開頭移動offset個字節
SEEK_CUR:從當前位置移動offset個字節
SEEK_END:從文件末尾移動offset個字節
返回值:
成功:0
失敗:-1
*/
2、rewind():
作用:将光标移動到開頭,和fseek(fp,0,SEEK_SET)一樣。
格式:
void rewind(FILE *stream);
/*
功能:把文件流(文件光标)的讀寫位置移動到文件開頭。
參數:
stream:已經打開的文件指針
返回值:
無返回值
*/
3、 ftell():
格式:
long ftell(FILE *stream);
/*
功能:獲取文件流(文件光标)的讀寫位置。
參數:
stream:已經打開的文件指針
返回值:
成功:當前文件流(文件光标)的讀寫位置
失敗:-1
*/
格式:
int stat(const char *path, struct stat *buf);
/*
功能:獲取文件狀态信息
參數:
path:文件名
buf:保存文件信息的結構體
返回值:
成功:0
失敗:-1
*/
struct stat {
dev_t st_dev; //文件的設備編号
ino_t st_ino; //節點
mode_t st_mode; //文件的類型和存取的權限
nlink_t st_nlink; //連到該文件的硬連接數目,剛建立的文件值為1
uid_t st_uid; //用戶ID
gid_t st_gid; //組ID
dev_t st_rdev; //(設備類型)若此文件為設備文件,則為其設備編号
off_t st_size; //文件字節數(文件大小)
unsigned long st_blksize; //塊大小(文件系統的I/O 緩沖區大小)
unsigned long st_blocks; //塊數
time_t st_atime; //最後一次訪問時間
time_t st_mtime; //最後一次修改時間
time_t st_ctime; //最後一次改變時間(指屬性)
};
代碼演示一下,如下所示:
#define __CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(){
struct stat stu;
int res = 0;
res = stat("./test.txt", &stu);
if (res < 0) {
printf("沒找到文件!\n");
}
printf("文件大小為:%d\n", stu.st_size);
system("pause");
return 0;
}
我這個文件因為是存在,而且文件有内容,所以會打印出文件大小,如下圖所示:
remove()與rename():
1、remove():
格式:
int remove(const char *pathname);
/*
功能:删除文件
參數:
pathname:文件名
返回值:
成功:0
失敗:-1
*/
2、rename():
格式:
int rename(const char *oldpath, const char *newpath);
/*
功能:把oldpath的文件名改為newpath
參數:
oldpath:舊文件名
newpath:新文件名
返回值:
成功:0
失敗: - 1
*/
注意問題:
緩沖區:就是内存中的一塊臨時的空間,同時普通文件刷新緩沖區的方法,有以下3種:
1、緩沖區滿了;2、程序正常退出時;3、利用fflush函數強制刷新。
windows與Linux的區别:
1、Windows下标準輸出stdout文件沒有緩沖區;
2、Linux有緩沖區;
标準輸入不能調用fflush強制刷新;
3、\n換行的問題。
在windows,輸入nihao\n時,存儲的是nihao\r\n,取出時是nihao\n,當在Linux系統下打開windows存儲的文件時,就會多了一個\r。
在Linux,輸入nihao\n時,存儲和取出都是nihao\n,而在windows下打開Linux存儲的文件時,發現沒有換行。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!