1. 程式人生 > >【C語言】檔案常用讀寫操作(含讀取學生資訊示例)

【C語言】檔案常用讀寫操作(含讀取學生資訊示例)

C檔案概述

檔案是指一組相關資料的有序集合。這個資料集有一個名稱,叫做檔名。實際上我們在C語言程式設計中已經多次使用了檔案。例如源程式檔案(.c)、目標檔案(.0bj)、可執行檔案(.exe)、庫檔案(標頭檔案)等。檔案通常是駐留在外部介質(如磁碟等)上的,在使用時才調入記憶體中來。(這就是為什麼對檔案操作的是需要開啟關閉

檔案分類

有很多種分類我這裡暫時就只介紹一種分類方式。也就是我們在C語言檔案操作中用到的二進位制ASCII方式。

二進位制檔案

形式:把記憶體中的資料按其在記憶體中的儲存形式原樣輸出到磁碟上存放。

優點:可以節省外存空間和轉換時間。 缺點:一個位元組並不對應一個字元,不能直接輸出字元形式。
一般中間結果資料需要暫時儲存在外存上,以後又需要輸入記憶體的,常用二進位制檔案儲存。

ASCII檔案(文字檔案)

形式:每一個位元組放一個ASCII程式碼。 優點:便於對字元進行逐個處理,也便於輸出字元。 缺點:一般佔儲存空間較多,而且要花費轉換時間。

對比儲存圖


補充內容

緩衝檔案系統

C語言中對檔案的讀寫都是用庫函式來實現的。對二進位制檔案和文字檔案都採用緩衝檔案系統。

UNIX系統對文字檔案採用緩衝檔案系統,二進位制檔案採用非緩衝檔案系統

事實上,當寫入檔案時,並不會馬上寫入磁碟中,而是先寫入緩衝區,只有緩衝區已滿或“關閉檔案”時,才會將資料寫入磁碟。如果沒有緩衝區的話對檔案的讀寫都需要另外的函式,這樣速度很慢而且也不是C語言自身的函式。


C語言檔案指標定義



檔案的開啟與關閉

fopen函式 標頭檔案:stdio.h 功    能:以type方式開啟filename檔案並返回該檔案的指標 用    法:FILE *fopen(char *filename,char *type); 返回值:filename的檔案指標
注意: 1.凡用“r”開啟一個檔案時,該檔案必須已經存在,且只能從該檔案讀出。 2.用“w”開啟的檔案只能向該檔案寫入。若開啟的檔案不存在,則以指定的檔名建立該檔案,若開啟的檔案已經存在,則將該檔案刪去,重建一個新檔案。若以寫或讀寫方式開啟一個已存在的檔案時將清除原來檔案的內容,希望寫入的字元以檔案末開始存放,必須以追加方式開啟檔案。
3.若要向一個已存在的檔案追加新的資訊,只能用“a”方式開啟檔案。但此時該檔案必須是存在的,否則將會出錯。 fclose函式 標頭檔案:stdio.h 功   能:關閉一個流 用   法:int fclose(FILE *stream); 返回值:成功返回0,不成功返回EOF(-1)

檔案的讀寫(標頭檔案均為stdio.h)

字元讀寫函式

fgetc函式 功   能:從fp所指向的檔案中讀取字元 用   法:int fgetc(FILE *fp); 返回值:返回檔案fp所指向的檔案中的字元值(EOF為檔案尾) 補   充: 1.呼叫該函式時,檔案使用方式必須是以讀或讀寫方式開啟的。 2.在檔案內部有一個位置指標,用來指向檔案的當前讀寫 fputc函式 功能:將字元(ch的值)輸出到fp所指向的檔案中去。 用法:int futc(int ch,FILE *fp); 返回值:寫入成功返回寫入字元ch              不成功返回EOF 示例:
#include <stdio.h>
int main()
{
	FILE *fp;
    char ch,filename[20];
	printf("Please input your filename:");
	scanf("%s",filename);
    if(!(fp=fopen(filename,"w")))
	{
		printf("Can not open %s\n",filename);
	}
	else
	{
		printf("Please input the sentences you write:");
		ch=getchar();
		ch=getchar();
        while(ch!=EOF)
		{
			fputc(ch,fp);
			ch=getchar();
		}
		fclose(fp);
	}
	    if(!(fp=fopen(filename,"r")))
	{
		printf("Can not open %s\n",filename);
	}
	else
	{
		printf("The content of %s is:",filename);
        while(!feof(fp))
		{
			ch=fgetc(fp);
			putchar(ch);
		}
		printf("\n");
		fclose(fp);
	}
	return 0;
}


字串讀寫函式

fgets函式 功   能:從fp所指向的檔案(stdin特殊檔案)中讀取長度為n的字串儲存到string中 用   法:char *fgets(char *string, int n, FILE *fp); 返回值:成功,返回string              失敗,返回NULL
fputs函式 功   能:將字串string寫入fp所指向的檔案中。 用   法:int fputs(char *string, FILE *fp); 返回值:輸入成功,返回值0              輸入失敗,返回EOF
示例:
#include <stdio.h>
#define LEN 100
int main()
{
	FILE *fp;
    char ch,string[LEN],filename[20],string1[LEN];

	printf("Please input your filename:");
	scanf("%s",filename);

    if(!(fp=fopen(filename,"w")))
	{
		printf("Can not open %s\n",filename);
	}
	else
	{
		printf("Please input the sentences you write:");
		ch=getchar();
		fgets(string,LEN,stdin);
        if(!fputs(string,fp))
			printf("寫入成功\n");
		else
			printf("寫入失敗\n");
		fclose(fp);
	}

	    if(!(fp=fopen(filename,"r")))
	{
		printf("Can not open %s\n",filename);
	}
	else
	{
		printf("The content of %s is:",filename);
        fgets(string1,LEN,fp);
		printf("%s\n",string1);
		fclose(fp);
	}
	return 0;
}


資料塊讀寫函式

fread函式 功   能:從fp指向的檔案中讀取n個size大小的資料寫入ptr指向的地方 用   法:int fread(void *ptr, int size, int n, FILE *fp); 返回值:成功,返回讀取元素個數      不成功,返回0 引數說明: ptr:讀入資料的存放地址(首地址) size:要讀寫的位元組數 n:要進行讀寫多少個size位元組的資料項
fwrite函式 功   能: 從ptr指向的地方讀取n個size大小的資料寫入fp指向的檔案中 用   法:int fwrite(void *ptr, int size, int n, FILE *fp); 返回值:返回寫入檔案的實際個數 引數說明:ptr:輸出資料的地址(首地址)其餘同上 注意:這個函式以二進位制形式對檔案進行操作,不侷限於文字檔案
示例:
#include <stdio.h>
#define SIZE 5
typedef struct
{
	char name[20];
	char num[15];
	int age;
}student;
student stu[SIZE],buf[SIZE];;
bool save();
void read();

int main()
{
   int i;
   for(i=0;i<SIZE;i++)
	   scanf("%s %s %d",&stu[i].name,&stu[i].num,&stu[i].age);
	//fread(&stu[i],sizeof(student),1,stdin);
 if(save())
  { 
     read();
   for(i=0;i<SIZE;i++)
		printf("name:%s num:%s age:%d\n",buf[i].name,buf[i].num,buf[i].age);
   }
   return 0;
}

bool save()
{
	FILE *fp;
    int i;
	char filename[50];

	printf("Please input your filename:");
	scanf("%s",filename);
    if(!(fp=fopen(filename,"wb")))
	{
		printf("Can not open %s\n",filename);
		return false;
	}
		for(i=0;i<SIZE;i++)
			if(fwrite(&stu[i],sizeof(student),1,fp)!=1)
				printf("檔案寫入失敗!\n");
		fclose(fp);
	return true;
}

void read()
{
	FILE *fp;
    int i;
	char filename[50];

	printf("Please input the filename you want read:");
	scanf("%s",filename);
    if(!(fp=fopen(filename,"r")))
	{
		printf("Can not open %s\n",filename);
		return;
	}
		for(i=0;i<SIZE;i++)
			if(fread(&buf[i],sizeof(student),1,fp)!=1)
				printf("檔案讀取失敗!\n");
		fclose(fp);
}
/*
Alice 001 18
Bob 002 18
Cobe 003 18
Dalin 004 18
Ela 005 18
*/




格式化讀寫函式

fscanf函式 功   能:從磁碟檔案中按格式讀入字元 用   法:int fscanf(FILE *fp, char *format,[argument...]); 示   例:fscanf(fp,"%d,%f",&i,&t); 返回值:成功返回讀入的引數的個數      失敗返回EOF(-1) 注   意:fscanf遇到空格和換行時結束,注意空格時也結束。
fprintf函式 功   能:從磁碟檔案中按格式輸出字元 用   法:int fprintf(FILE *fp, char *format,[argument...]); 示   例:fprintf(fp,"%d,%6.2f",i,t); 返回值:成功返回輸出的字元數      失敗時返回一個負值.
示例:
#include <stdio.h>
#define SIZE 5
typedef struct
{
	char name[20];
	char num[15];
	int age;
}student;
student stu[SIZE],buf[SIZE];


int main()
{
  FILE *fp;
  char filename[50],ch;
  printf("input your name num and age:\n");
  fscanf(stdin,"%s %s %d",&stu[0].name,&stu[0].num,&stu[0].age);//stdin為鍵盤輸入

  printf("Please input your read filename:");
  scanf("%s",filename);
  if(!(fp=fopen(filename,"w")))
  {
	  printf("Can not open %s",filename);
	  return 1;
  }
  fprintf(fp,"name:%s num:%s age:%d",stu[0].name,stu[0].num,stu[0].age);
  fclose(fp);

  return 0;
}

/*
Alice 001 18
*/



總結

1.用fopen開啟檔案 2.採用自己需要的方式寫檔案或讀檔案 3.用fclose關閉檔案