1.打開和關閉
int main() {
char path[] = "Hole.txt"; //這裏使用的是相對路徑。
FILE* file = fopen(path, "a+");
/*
"r" 打開一個用於讀取的文本文件。文件必須存在。不存在則出錯。
"w" 打開一個用於寫入的文本文件。若文件存在則文件長度清爲0,即文件內容會消失。若文件不存在則建立該文件。
"a" 附加到一個文本文件。若文件存在,寫入的數據會被加到文件尾,即文件原先的內容會被保留。若文件不存在,則會建立該文件。
"rb" 打開一個用於讀取的二進制文件。
"wb" 打開一個用於寫入的二進制文件。
"ab" 附加到一個二進制文件。
"r+" 打開一個用於讀/寫的文本文件。若文件不存在則出錯。
"w+" 打開一個用於讀/寫的文本文件。
"a+" 附加到一個用於讀/寫的文本文件。
"rb+" 打開一個用於讀/寫的二進制文件。
"wb+" 打開一個用於讀/寫的二進制文件。
"ab+" 附加到一個用於讀/寫的二進制文件。
返回值:正常返回:FILE* 一個指向文件在內存中的文件信息塊的指針。
異常返回:NULL,表示打開操作不成功。
*/
/*
要說明的是:C語言將計算機的輸入輸出設備都看作是文件。
例如,鍵盤文件、屏幕文件等。
ANSI C標準規定,在執行程序時系統先自動打開鍵盤、屏幕、錯誤三個文件。
這三個文件的文件指針分別是:標準輸入stdin、標準輸出stdout和標準出錯stderr。
*/
std::cout << file << std::endl;
int ch = fgetc(file); //從fp所指文件的當前指針位置讀取一個字符
while(ch != EOF)
{
putchar(ch); //若不是結束符,將它輸出到屏幕上顯示
std::cout << " ";
std::cout << ch << std::endl;
ch = fgetc(file); //從fp所指文件的當前指針位置讀取一個字符
}
int i = fputc('a', file); //向文件中寫入一個字符。第一個參數是待寫入的字符,第二個參數是字符寫入的文件(指向字符寫入的文件的指針。)
std::cout << i << std::endl;
int ret = fclose(file); //這個函數的參數就是指向打開文件的指針。
//一定要記住在打開一個文件之後,操作完之後關閉它。
/*正常返回:0
異常返回:EOF,表示文件在關閉時發生錯誤
*/
std::cout << ret << std::endl;
return 0;
}
請看,file的值是地址。
上面的代碼裏面還有fgetc()函數和fputc()函數,他們的作用分別是取文件裏面的字符和向文件裏面寫入字符。
但是我在調試的時候發現了一個問題,那就是上面的操作是將打開文件裏面的字符全都讀取出來之後,再在文件尾寫入一個字符,這樣可以正常寫入,但是如果只是讀了一個字符的話,再用fputc()函數寫入一個字符就寫不進去,但是問題是函數正確的執行了,返回值也是正確的,但是文件裏面卻沒有剛寫入的字符。很是奇怪!
經過在CSDN發問答帖,得到大佬指點,加一個函數就可以解決了。
fseek(file, 0L, SEEK_END); //把文件指針定位到末尾
//文件指針定位到文件末尾,偏移0個字節
int main() {
char path[] = "Hole.txt"; //這裏使用的是相對路徑。
FILE* file = fopen(path, "a+");
std::cout << file << std::endl;
int ch = fgetc(file); //從fp所指文件的當前指針位置讀取一個字符
if (ch != EOF) {
putchar(ch);
std::cout << std::endl;
}
fseek(file, 0L, SEEK_END); //把文件指針定位到末尾
//文件指針定位到文件末尾,偏移0個字節
int i = fputc('a', file); //向文件中寫入一個字符。第一個參數是待寫入的字符,第二個參數是字符寫入的文件(指向字符寫入的文件的指針。)
std::cout << i << std::endl;
int ret = fclose(file); //這個函數的參數就是指向打開文件的指針。
std::cout << ret << std::endl;
return 0;
}
這樣就可以在讀了一個字符之後,然後通過fseek()函數把文件指針定位到末尾,這樣就可以在末尾加入字符了。
2.寫入、讀出字符
fgetc()函數和fputc()函數上面的那個小節已經介紹並使用了。
fseek()函數
void rewind(FILE *fp); //用來將文件指針移動到文件頭。
int fseek(FILE *fp, long offset, int fromwhere);
//offset是偏移量,fromwhere的取值有三個。
//SEEK_SET 0 表示文件開頭
//SEEK_CUR 1 表示文件當前位置
//SEEK_END 2 表示文件末尾
例如:
範例一:fseek(fp,0L,SEEK_END);
解釋:文件指針定位到文件末尾,偏移0個字節。
範例二:fseek(fp,50L,0)或fseek(fp,50L,SEEK_SET);
解釋:其作用是將位置指針移到離文件頭50個字節處。
offset是long型數據,它表示位置指針相對於fromwhere移動的字節數。
如果位移量是一個正數,表示從fromwhere開始往文件尾方向移動;如果位移量是一個負數,則表示從fromwhere開始往文件頭方向移動。
3.從文件中讀取字符串,向文件中寫入字符串
使用fgets()函數從文件中讀取字符串,使用fputs()函數向文件中寫入字符串。
fgets()函數使用說明:
由fp指出的文件中讀取n-1個字符,並把他們存放到str指向的字符數組中,最後加上一個字符串結束符'\0'。
char *fgets(char *str, int n, FILE *fp)
參數說明:
str:接受字符串的內存地址,可以是數組別名,也可以是指針
n:指出要讀取的字符的個數
fp:這個是文件指針,指出要從中讀取字符的文件
返回值:
正常返回:字符串的內存首地址,即str的值
異常返回:返回一個NULL值,此時應當用feof()或ferror()函數來判別是讀取到了文件尾,還是發生了錯誤。
int main() {
char path[] = "Hole.txt"; //這裏使用的是相對路徑。
FILE* file = fopen(path, "ab+");
char path1[] = "Hole1.txt";
FILE* file1 = fopen(path1, "ab+");
const int SIZE = 7;
char buffer[SIZE];
while (fgets(buffer, SIZE, file) != NULL) {
fputs(buffer,file1);
}
int ret = fclose(file); //這個函數的參數就是指向打開文件的指針。
fclose(file1);
return 0;
}
這個函數實現的是將Hole.txt的文件裏的字符串讀出,把它們寫入Hole1.txt中。
4.往文件中寫格式化數據,格式化讀取文件中的數據
int fprintf(FILE *fp,const char *format,arg_list)
將變量表列(arg_list)中的數據,按照format指出的格式,寫入由fp指定的文件。fprintf()函數與printf()函數的功能相同,只是printf()函數是將數據寫入屏幕文件(stdout)。
fp:這是個文件指針,指出要將數據寫入的文件。
format:這是個指向字符串的字符指針,字符串中含有要寫出數據的格式,所以該字符串成爲格式串。格式串描述的規則與printf()函數中的格式串相同。
arg_list:是要寫入文件的變量表列,各變量之間用逗號分隔。
int fscanf(FILE *fp, const char *format, agars)
fscanf():從文件指針fp指向的文件中,按format中對應的控制格式讀取數據,並存儲在agars對應的變量中。
一個完美的演示的例子。
#include <stdio.h>
void main() {
char name[10];
int nAge, nClass;
long number;
FILE* fp;
if ((fp = fopen("student.txt", "w")) == NULL)
{
printf("The file %s can not be opened.\n", "student.txt");
return;
}
fscanf(stdin, "%s %d %d %ld", name, &nClass, &nAge, &number);
fprintf(fp, "%s %5d %4d %8ld", name, nClass, nAge, number);
fclose(fp);
if ((fp = fopen("student.txt", "r")) == NULL)
{
printf("The file %s can not be opened.\n", "student.txt");
return;
}
fscanf(fp, "%s %d %d %ld", name, &nClass, &nAge, &number);
printf("name nClass nAge number\n");
fprintf(stdout, "%-10s%-8d%-6d%-8ld\n", name, nClass, nAge, number);
fclose(fp);
}
5.以二進制形式讀取文件中的數據、以二進制形式寫數據到文件中去
int fread(void *buffer,unsigned size,unsigned count,FILE *fp)
從由fp指定的文件中,按二進制形式將size*count個數據讀到由buffer指出的數據區中。
buffer:這是一個void型指針,指出要將讀入數據存放在其中的存儲區首地址。
size:指出一個數據塊的字節數,即一個數據塊的大小尺寸。
count:指出一次讀入多少個數據塊。
fp:這是個文件指針,指出要從其中讀出數據的文件。
正常返回:實際讀取數據塊的個數,即count。
異常返回:如果文件中剩下的數據塊個數少於參數中count指出的個數,或者發生了錯誤,返回0值。此時可以用feof()和ferror()來判定到底出現了什麼情況。
int fwrite(void *buffer,unsigned size,unsigned count,FILE *fp)
按二進制形式,將由buffer指定的數據緩衝區內的size*count個數據寫入由fp指定的文件中去。
buffer:這是一個void型指針,指出要將其中數據輸出到文件的緩衝區首地址。
size:指出一個數據塊的字節數,即一個數據塊的大小尺寸。
count:一次輸出多少個數據塊。
fp:這是個文件指針,指出要從其中讀出數據的文件。
正常返回:實際輸出數據塊的個數,即count。
異常返回:返回0值,表示輸出結束或發生了錯誤。
6.以二進制形式讀取一個整數、以二進制形式存儲一個整數
int getw(FILE *fp)
從由fp指定的文件中,以二進制形式讀取一個整數。
fp:是文件指針。
正常返回:所讀取整數的值。
異常返回:返回EOF,即-1。由於讀取的整數值有可能是-1,所以必須用feof()或ferror()來判斷是到了文件結束,還是出現了一個出錯。
int putw(int n,FILE *fp)
以二進制形式把由變量n指出的整數值存放到由fp指定的文件中。
n:要存入文件的整數。
fp:是文件指針。
正常返回:所輸出的整數值。
異常返回:返回EOF,即-1。由於輸出的整數值有可能是-1,所以必須用feof()或ferror()來判斷是到了文件結束,還是出現了一個出錯。