C/C++文件操作 超全的解釋 還有代碼演示

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()來判斷是到了文件結束,還是出現了一個出錯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章