C-文件讀寫

一.文件的打開與關閉

  • 為了讀寫文件,我們需要用到定義在stdio.h這個標準庫頭文件中的一些函數(shù)結構
  • 下面按順序列出我們打開一個文件,進行讀寫操作所必須遵循的一個流程
    1.調用“文件打開”函數(shù)fopen,返回一個指向該文件的指針
    2.檢測文件是否打開成功,通過第一步fopen的返回值(文件指針)來判斷,如果指針為NULL,則表示打開失敗,我們需要停止操作,并且返回一個錯誤
    3.如果文件打開成功,就可以用stdio.h中的讀寫函數(shù)來讀寫文件
    4.完成讀寫操作,關閉文件,調用“文件關閉”函數(shù)fclose

1.fopen:打開文件

//函數(shù)原型
FILE* fopen(const char* fileName,const char* openMode);
  • fileName:文件名,字符串類型,不可變
  • openMode:打開方式,表明我們打開文件之后要干什么
可用的openMode
  • 函數(shù)返回值:FILE指針

2.fclose:關閉文件

//函數(shù)原型
int fclose(FILE* pointerOnFile);
  • pointerOnFile:指向文件文件的指針
  • 函數(shù)的返回值(int)有兩種情況:
    1.0:當關閉操作成功時
    2.EOF(一般是-1):如果關閉失敗
  • 關閉這個文件,目的是為了釋放占用的文件指針

二.讀寫文件的不同方法

學習如何對文件進行讀出和寫入

1.對文件寫入

我們學習三個寫入的函數(shù)

  • fputc:file put character,在文件中寫入一個字符
  • fputs:file put string,在文件中寫入一個字符串
  • fprint:在文件中寫入一個格式化過的字符串,用法與printf幾乎相同,只是多了一個文件指針

fputc

int fputc(int character, FILE*pointerOnFile);
  • character:int型變量,表示要寫入的字符
  • pointerOnFile:指向文件的指針
  • 函數(shù)返回值int:如果寫入失敗,則為EOF,否則會是另一個值

示例:

//程序用于向test.txt寫入字符'A'
#include <stdio.h>
int main(int argc, const char* argv[]) {
    FILE* file = NULL;
    file = fopen("/Users/xulei/Desktop/test.txt", "w");
    if (file == NULL) {
        printf("error");
    }
    fputc('A', file);
    fclose(file);
    return 0;
}

運行之后,會在我所給的路徑(桌面)下,創(chuàng)建一個test.txt

test.txt

fputs

int fputs(const char* string, FILE* pointerOnFile);
  • stringr:char型變量,表示要寫入的字符串
  • pointerOnFile:指向文件的指針
  • 函數(shù)返回值int:如果寫入失敗,則為EOF,否則會是另一個值

示例:

//程序用于向test.txt寫入字符串
#include <stdio.h>
int main(int argc, const char* argv[]) {
    FILE* file = NULL;
    file = fopen("/Users/xulei/Desktop/test1.txt", "w");
    if (file == NULL) {
        printf("error");
    }
    fputs("你好,朋友\n最近怎么樣", file);
    fclose(file);
    return 0;
}

運行之后,會在我所給的路徑(桌面)下,創(chuàng)建一個test1.txt

test1.txt

fprintf

int fprintf(FILE* stream, const char *format, ...);

不僅可以向文件寫入字符串,而且這個字符串可以有由我們來格式化

示例:

//程序用于向test.txt寫入字符串
#include <stdio.h>
int main(int argc, const char* argv[]) {
    FILE* file = NULL;
    int age = 0;
    file = fopen("/Users/xulei/Desktop/test2.txt", "w");
    if (file == NULL) {
        printf("error");
    }
    printf("你幾歲了?\n");
    scanf("%d",&age);
    fprintf(file, "使用者年齡是%d歲\n",age);
    fclose(file);
    return 0;
}
//運行結果
你幾歲了?

2
Program ended with exit code: 0

運行之后,會在我所給的路徑(桌面)下,創(chuàng)建一個test2.txt

test2.txt

2.對文件讀出

我們學習三個讀出的函數(shù)

  • fgetc:file get character,在文件中讀出一個字符
  • fgets:file get string,在文件中讀出一個字符串
  • fscanf:在文件中讀出一個格式化過的字符串,用法與scanf幾乎相同,scanf是從用戶輸入讀取,而fscanf是從文件讀取

fgetc

int fgetc(FILE*pointerOnFile);
  • pointerOnFile:指向文件的指針
  • 函數(shù)返回值int:函數(shù)返回值是讀到的字符,如果不能讀到字符,那會返回EOF
  • fgetc函數(shù)每讀入一個字符,這個虛擬的游標就移動這個一個字符長度,我們就可以用一個循環(huán)讀出所有的字符
    示例:
#include <stdio.h>
int main(int argc, const char * argv[]) {
    FILE* file = NULL;
    int currentCharacter = 0;
    file = fopen("/Users/xulei/Desktop/test2.txt", "r");
    if (file == NULL) {
        printf("error");
    }
    do {
        currentCharacter = fgetc(file);//讀取一個字符
        printf("%c",currentCharacter);//顯示讀取的字符
    } while (currentCharacter != EOF);
    printf("\n");
    fclose(file);
    return 0;
}
//運行結果
使用者年齡是2歲
\377
Program ended with exit code: 0
//\377,其實就是-1,也就是EOF,表示讀到末尾
/*
\是C語言的轉義字符的起始標識。
當\后面直接接數(shù)字的時候,會被處理成對應的8進制。
于是\377也就是8進制377對應的ascii碼值,將其轉為二進制為
3 = 11
7 =111
于是值為11 111 111
也就是16進制的0xff, 10進制值為255。
這個是單字節(jié)無符號數(shù)所能表示的最大值,作為有符號數(shù)時,值為-1
*/

fgets

char *fgets(char *string, int characterNumberToRead, FILE* pointerOnFile);

這個函數(shù)每次最多讀一行,因為它遇到第一個'\n'(換行符)會結束讀取

示例:

#include <stdio.h>
int main(int argc, const char * argv[]) {
    FILE* file = NULL;
    char string[1000] = " ";//保證數(shù)組足夠大
    file = fopen("/Users/xulei/Desktop/test1.txt", "r");
    if (file == NULL) {
        printf("error");
    }
    while (fgets(string, 1000, file) != NULL) {//只要某一行不是空值就讀取它
        printf("%s\n",string);
    }
    fclose(file);
    return 0;
}
//運行結果
你好,朋友

最近怎么樣
Program ended with exit code: 0

fscanf

int fscanf(FILE* stream, const char *format, ...);

此函數(shù)原理和scanf是一樣的,負責從文件中讀取規(guī)定樣式的內容

示例:

#include <stdio.h>
int main(int argc, const char * argv[]) {
    FILE* file = NULL;
    int score[3] = {30,19,32,};
    //文件寫入
    file = fopen("/Users/xulei/Desktop/test3.txt", "w");
    if (file == NULL) {
        printf("error");
    }
    for (int i = 0; i < 3; i++) {
        fputc(i, file);
    }
    fclose(file);
    //文件讀取
    file = fopen("/Users/xulei/Desktop/test3.txt", "r");
    if (file == NULL) {
        printf("error");
    }
    fscanf(file, "%d %d %d",&score[0],&score[1],&score[2]);
    printf("%d %d %d",score[0],score[1],score[2]);
    printf("\n");
    fclose(file);
    return 0;
}
//運行結果
30 19 32
Program ended with exit code: 0

三.在文件中移動

前面我們提到一個虛擬的游標,現(xiàn)在我們仔細學一下
每當我們打開一個文件時,實際上都存在一個游標,標識你當前在文件中所處的位置,可以類比我們編輯文本時的光標

三個與文件中游標移動有關的函數(shù):

  • ftell:告訴目前在文件中那個位置
  • fseek:移動文件中的游標到指定位置
  • rewind:將游標重置到文件的開始位置

ftell

返回一個long型的整數(shù)值,表明目前游標所在位置

long ftell(FILE* pointerOnFile);

fseek

此函數(shù)能使游標在文件(pointerOnFile指針所指)中從位置(origin所指)開始移動一段距離(move所指)

int fseek(FILE* pointerOnFile, long move, int origin);
  • move:可以是一個正整數(shù),表明向前移動;0,不移動;負整數(shù),表明回退
  • origin:它有三個取值
    1.SEEK_SET:文件開始處
    2.SEEK_CUR:游標當前所處位置
    3.SEEK_END:文件末尾

例子:

fseek(file, 5, SEEK_SET);
//這行代碼將游標放置到距離文件開始處5個位置的地方。

fseek(file, -3, SEEK_CUR);
//這行代碼將游標放置到距離當前位置往后3個位置的地方

fseek(file, 0, SEEK_END);
//這行代碼將游標放置到文件末尾。

rewind

相當于使用fseek來使游標回到0的位置

void remind(FILE* pointerOnFile);
//相當于fseek(file,0,SEEK_SET);

四.文件的重命名和刪除

兩個簡單的函數(shù):

  • rename:重命名一個文件
  • remove:刪除一個文件

rename

int rename(const char *oldName, const char *newName);

如果函數(shù)執(zhí)行成功,則返回0,否則返回非0的int型值

示例:

int main(int argc, char *argv[]){
  rename("test.txt", "renamed_test.txt");
  return 0;
}

remove

int remove(const char *fileToRemove);

fileToRemove就是我們要刪除的文件名

示例:

int main(int argc, char *argv[]){
  remove("test.txt");
  return 0;
}

五.數(shù)據(jù)塊讀寫函數(shù)fread 和 fwrite

讀數(shù)據(jù)塊數(shù)據(jù)的格式: fread(buffer,size,count,fp);
寫數(shù)據(jù)塊數(shù)據(jù)的格式: fwrite(buffer,size,count,fp);

  • buffer -- 是一個指針,在fread函數(shù)中,它表示存放輸入數(shù)據(jù)的首地址。在fwrite函數(shù)中,它表示存放輸出數(shù)據(jù)的首地址。

  • size -- 表示數(shù)據(jù)庫的字節(jié)數(shù)

  • count -- 表示要讀寫的數(shù)據(jù)庫塊數(shù)

  • fp -- 表示文件指針

fread(fa,4,5,fp); --> 意義: 是從fp所指的文件中,每次讀4個字節(jié)(一個實數(shù))送入實數(shù)組fa中,連續(xù)5次,即讀5個實數(shù)到fa中

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容