C語言文件讀寫操作總結


文件的基本操作

      文件的打開操作 fopen 打開一個文件
      文件的關閉操作 fclose 關閉一個文件
      文件的讀寫操作 fgetc 從文件中讀取一個字符
              fputc 寫一個字符到文件中去
              fgets 從文件中讀取一個字符串
              fputs 寫一個字符串到文件中去
              fprintf 往文件中寫格式化數據
              fscanf 格式化讀取文件中數據
              fread 以二進制形式讀取文件中的數據
              fwrite 以二進制形式寫數據到文件中去
              getw 以二進制形式讀取一個整數
              putw 以二進制形式存貯一個整數
    文件狀態檢查函數 feof 文件結束
              ferror 文件讀/寫出錯
              clearerr 清除文件錯誤標志
              ftell 了解文件指針的當前位置
       文件定位函數 rewind 反繞
              fseek 隨機定位

文件打開與關閉

文件打開函數原型

FILE *fopen(char *pname,char *mode)

按照mode 規定的方式,打開由pname指定的文件。若找不到由pname指定的相應文件,就按以下方式之一處理:

  • (1) 此時如mode 規定按寫方式打開文件,就按由pname指定的名字建立一個新文件;
  • (2) 此時如mode 規定按讀方式打開文件,就會產生一個錯誤。

打開文件的作用

  • (1)分配給打開文件一個FILE 類型的文件結構體變量,並將有關信息填入文件結構體變量;
  • (2)開辟一個緩沖區;
  • (3)調用操作系統提供的打開文件或建立新文件功能,打開或建立指定文件;

FILE *:指出fopen是一個返回文件類型的指針函數;

參數說明

  • pname:是一個字符指針,它將指向要打開或建立的文件的文件名字符串。
  • mode:是一個指向文件處理方式字符串的字符指針。為打開模式。模式可以有r(允許讀取),r+(允許讀寫),w(允許寫入),a(允許追加)等
模式 描述
r 打開一個已有的文本文件,允許讀取文件。
w 打開一個文本文件,允許寫入文件。如果文件不存在,則會創建一個新文件。在這里,您的程序會從文件的開頭寫入內容。如果文件存在,則該會被截斷為零長度,重新寫入。
a 打開一個文本文件,以追加模式寫入文件。如果文件不存在,則會創建一個新文件。在這里,您的程序會在已有的文件內容中追加內容。
r+ 打開一個文本文件,允許讀寫文件。
w+ 打開一個文本文件,允許讀寫文件。如果文件已存在,則文件會被截斷為零長度,如果文件不存在,則會創建一個新文件。
a+ 打開一個文本文件,允許讀寫文件。如果文件不存在,則會創建一個新文件。讀取會從文件的開頭開始,寫入則只能是追加模式。

返回值

  • 正常返回:被打開文件的文件指針。
  • 異常返回:NULL,表示打開操作不成功。

說明:C語言將計算機的輸入輸出設備都看作是文件。例如,鍵盤文件、屏幕文件等。ANSI C標准規定,在執行程序時系統先自動打開鍵盤、屏幕、錯誤三個文件。這三個文件的文件指針分別是:標准輸入stdin、標准輸出stdout和標准出錯 stderr。

文件關閉函數原型

int fclose(FILE *fp);

功能說明

  • 關閉由fp指出的文件。此時調用操作系統提供的文件關閉功能,關閉由fp->fd指出的文件;釋放由fp指出的文件類型結構體變量;返回操作結果,即0或EOF。

參數說明

  • fp:一個已打開文件的文件指針。

 返回值

  • 正常返回:0。  
  • 異常返回:EOF(-1),表示文件在關閉時發生錯誤。

文件的標准打開代碼

// C語言文件操作

# include <stdio.h>
# include <stdlib.h>
# include <string.h>

int main(void)
{
    FILE *fp = NULL; // 定義一個文件指針(此時操作位於緩沖區)

    if (NULL == (fp = fopen("aa.txt","r"))) // 判斷打開操作是否成功,如果aa.txt不存在的話,此時讀操作會出錯
    {  
        // fp = fopen("D:\\Programing\\11.txt","r"); // 另一種打開方式 windows中。Linux中采用 “/tmp/test.txt”
        printf("This file cannot be opened.\n");
        exit(1); // 結束程序執行 
    } 
    fclose(fp); 
    
    return 0;
}

文件寫入

文件寫入函數原型

int fputc(int ch,FILE *fp)

功能說明

  • 把ch中的字符寫入由fp指出的文件中去。

參數說明

  • ch:是一個整型變量,內存要寫到文件中的字符(C語言中整型量和字符量可以通用)。
  • fp:這是個文件指針,指出要在其中寫入字符的文件。

返回值

  • 正常返回: 要寫入字符的代碼。
  • 非正常返回:返回EOF。例如,要往"讀打開"文件中寫一個字符時,會發生錯誤而返回一個EOF。
// C語言文件操作

# include <stdio.h>
# include <stdlib.h>
# include <string.h>

int main(void)
{
    FILE *fp = NULL; // 定義一個文件指針

    if (NULL == (fp = fopen("aa.txt","w"))) // 若要進行文件的寫入,此處可以是 r+、w、a 
    {
        printf("This file cannot be opened.\n");
        exit(1); // 結束程序執行 
    } 
    fprintf(fp, "This is a test for fprintf...\n");
    fputs("This is a test for fputs...\n",fp);
    
    fclose(fp);     
    return 0;
}

文件讀取

文件讀取函數原型

int fgetc(FILE *fp);

功能說明

  • 從fp所指文件中讀取一個字符。

參數說明

  • fp:這是個文件指針,它指出要從中讀取字符的文件。

返回值

  • 正常返回: 返回讀取字符的代碼。
  • 非正常返回:返回EOF。例如,要從"寫打開"文件中讀取一個字符時,會發生錯誤而返回一個EOF。
// C語言文件讀取,並打印輸出

# include <stdio.h>
# include <stdlib.h>
# include <string.h>

int main(void)
{
    FILE *fp = NULL; // 定義一個文件指針
    int ch; // 接收文件中字符的ASCII碼數值 

    if (NULL == (fp = fopen("aa.txt","r"))) // 判斷打開操作是否成功
    {
        printf("This file cannot be opened.\n");
        exit(1); // 結束程序執行 
    } 
    
    ch = fgetc(fp); // 接收ASCII碼值,fp指針自動后移一位 
    
    while (ch != EOF)
    {
        putchar(ch);
        ch = fgetc(fp);
    }
    fclose(fp); 
    
    return 0;
}

從流中讀取一個字符串:

char *fgets( char *buf, int n, FILE *fp );

函數 fgets() 從 fp 所指向的輸入流中讀取 n - 1 個字符。它會把讀取的字符串復制到緩沖區 buf,並在最后追加一個 null 字符來終止字符串。

如果這個函數在讀取最后一個字符之前就遇到一個換行符 '\n' 或文件的末尾 EOF,則只會返回讀取到的字符,包括換行符。

也可以使用 int fscanf(FILE *fp, const char *format, ...) 函數來從文件中讀取字符串,但是在遇到第一個空格字符時,它會停止讀取。

# include <stdio.h>
# include <stdlib.h>
# include <string.h>

int main(void)
{
    FILE *fp = NULL; // 定義一個文件指針
    char buff[200];

    if (NULL == (fp = fopen("aa.txt","r"))) // 若要進行文件的寫入,此處可以是 r+、w、a 
    {
        printf("This file cannot be opened.\n");
        exit(1); // 結束程序執行 
    } 
/*    
    fputs("This is a test for fputs...\n",fp);
    fputs("This is a test for fprintf...\n",fp);
*/    
    fscanf(fp, "%s\n", buff);
    printf("1: %s\n", buff);  // 輸出 1:This 
    
    fgets(buff, 200, fp);
    printf("2: %s\n", buff); // 輸出  2:is a test for fputs...

    fgets(buff, 200, fp);
    printf("3: %s\n", buff); // 輸出  3: This is a test for fprintf...
    // 首先,fscanf() 方法只讀取了 This,因為它在后邊遇到了一個空格。
    // 其次,調用 fgets() 讀取剩余的部分,直到行尾。、
    // 最后,調用 fgets() 完整地讀取第二行。
    fclose(fp);     
    return 0;
}

對結構體文件的增、刪、查操作

函數名: rewind()
功 能 : 將文件內部的位置指針重新指向一個流(數據流/文件)的開頭
注意  : 不是文件指針而是文件內部的位置指針,隨着對文件的讀寫文件的位置指針(指向當前讀寫字節)向后移動。 
        而文件指針是指向整個文件,如果不重新賦值文件指針不會改變。
        rewind函數作用等同於 (void)fseek(stream, 0L, SEEK_SET); 
用 法 : void rewind(FILE *stream);
頭文件: stdio.h
清空輸入緩沖區操作
通常是為了確保不影響后面的數據讀取   
例如在讀完一個字符串后緊接着又要讀取一個字符,此時應該先執行fflush(stdin);
// Test_File 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

FILE *fmem;

typedef struct member
{
    char name[16];       // 姓名 
    int id;              // ID
    int phoneNumber;     // 手機號
    char email[64];      // 郵箱 
    char QQ[15];         // QQ 
    char wechat[15];     // 微信 
}members;

members m[100];   // 記錄會員信息 
int n=0;         // 會員 

// 輸入內容 
void gets_without_newline(char* str)
{
    fgets(str,128,stdin);
    str[strlen(str) - 1] = '\0';
}
// 用於計算文件的行數 
int linecount(FILE *pt)
{
    int x=0;
    char c;
    fscanf(pt,"%c",&c);
    while(!feof(pt))
    {
        if(c=='\n')
            x++;
        fscanf(pt,"%c",&c);
    }
    rewind(pt);             // rewind();函數的功能是 在文件內部指向數據流的開頭 
    return x;
}

// 加載會員信息 
int loadMembers()
{
    fmem=fopen("newmembers.txt","r");  // 只讀方式打開文件 

    if(fmem!=NULL)
    {
        int x=linecount(fmem);    // 計算文件的行數 
        while (n!=x)
        {
            // %[^,] 表示讀取任意字符,以“,”為結尾 
            fscanf(fmem,"%[^,],%d,%d,%s,%s,%s",m[n].name,&m[n].id,&m[n].phoneNumber,m[n].email,m[n].QQ,m[n].wechat);
            fscanf(fmem,"\n");  // 讀入一個換行符 
            n++;
        }
        fclose(fmem);
    }
    else
    {
        printf(" 會員信息為空!");
        return 0 ;
    }
    return n;
}

// 添加會員信息 
void addMembers ()
{
    int count,id,flag=0;
    fflush(stdin);   // 清空緩沖區 
    printf("輸入會員名字 ");
    gets_without_newline(m[n].name);
    
// 檢查該會員是否已經在列表中 
    do
    {flag=0;
        printf("請輸入會員 Id: ");
        scanf("%d",&id);
        for (count=0; count<n; count++)
        {
            if(id==m[count].id)
            {
                flag=1;
                break;
            }
        }
    }
    while(flag);

    m[n].id=id;

    fflush(stdin);
    printf("請輸入電話號碼: ");
    scanf("%d",&m[n].phoneNumber);
    fflush(stdin);
    printf("請輸入郵箱地址: ");
    gets_without_newline(m[n].email);
    fflush(stdin);
    printf("請輸入QQ號碼: ");
    gets_without_newline(m[n].QQ);
    fflush(stdin);
    printf("請輸入微信號碼: ");
    gets_without_newline(m[n].wechat);
   
    n++;
}

// 移除會員信息 
void remove_member()
{
    int i,j,k,borrowed=0,search,flag=0;

    printf("請輸入會員 ID: ");
    scanf("%d",&search);

    for(k=0; k<n; k++) // 第K行退出 
    {
        if(search==m[k].id)
            break;
    }
    
    i=k;
    
    while(i < (n-1))
    {
        m[i]=m[i+1];  // 直接用后面內容覆蓋前者 
        i++;
    }

    n=n-1;
}

// 保存會員信息 
void saveMembers()
{
    fmem=fopen("newmembers.txt","w");   // 對文件執行寫操作 
    int i;
    for(i=0; i<n; i++)
    {
        fprintf(fmem,"%s,%d,%d,%s,%s,%s",m[i].name,m[i].id,m[i].phoneNumber,m[i].email,m[i].QQ,m[i].wechat);
        fprintf(fmem,"\n");
    }
    fclose(fmem);
}

void DisplayMembers()
{
    int i;
    printf("會員信息: \n");
    for(i=0; i<n; i++)
    {
        printf("%s,%d,%d,%s,%s,%s",m[i].name,m[i].id,m[i].phoneNumber,m[i].email,m[i].QQ,m[i].wechat);
        printf("\n");
    }
}

int main(void)
{
    // 加載必要的文件 
    loadMembers();      // 加載到內存緩沖區 
    DisplayMembers();   // 從緩沖區讀取到屏幕 
    addMembers();       // 在緩沖區添加信息 
    remove_member();     
    saveMembers();      // 落盤 

    return 0;
}

RR


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM