C語言中文件操作

我們經常見到的文件寫入和讀取。

#include<iostream>

using namespace std;
typedef struct
{
	char no[10];
	char name[10];
	double foreign;
	double spec1;
	double spec2;
	double total;
}StudentType;
void WriteToFile();
void ReadFromFile();
int main()
{
	int select;
	do
	{
		printf("1:錄入成績2:輸出成績 0:退出\n");
		printf("請輸入要執行的操作");
		cin >> select;
		switch (select)
		{
		case 1:
			WriteToFile();
			break;
		case 2:
			ReadFromFile();
			break;
		default:
			cout << "退出程序" << endl;
			break;
		}
	} while ((select == 1 || select == 2));

	system("pause");
	return 0;
}
void WriteToFile()
{
	FILE *fp = NULL;
	StudentType stu;
	char flag = 'y';
	fp = fopen("student.txt", "a");//append 以追加的方式打開文件
	if (fp == NULL)
	{
		printf("打開文件失敗");
		exit(1);//以有錯的方式退出程序
	}
	while (flag == 'y' || flag == 'Y')
	{
		printf("請輸入考生考號:\n");
		scanf("%s", stu.no);
		printf("請輸入考生姓名\n");
		scanf("%s", stu.name);
		printf("請輸入學生的外語成績:\n");
		scanf("%lf", &stu.foreign);
		printf("請輸入考生的專業課一成績:\n");
		scanf("%lf", &stu.spec1);
		printf("請輸入考生的專業課二成績:\n");
		scanf("%lf", &stu.spec2);
		stu.total = stu.foreign + stu.spec1 + stu.spec2;
		fprintf(fp, "%10s%10s%8.2f", stu.no, stu.name, stu.foreign);
		fprintf(fp, "%8.2f%8.2f%8.2f", stu.spec1, stu.spec2, stu.total);
		fputc('\n', fp);
		fflush(stdin);//將鍵盤輸入的信息(緩衝區中的信息)刷新一下
		printf("繼續輸入嗎?繼續請輸入Y或者y");
		scanf("%c", &flag);
	}
	fclose(fp);
	return;
}

void ReadFromFile()
{
	FILE* fp = NULL;
	StudentType stu;
	fp = fopen("student.txt", "r");
	if (fp == NULL)
	{
		printf("打開文件失敗");
		exit(1);
	}
	printf("   考試姓名   總分\n");
	while (!feof(fp))//當沒有遇見文件結束符的時候
	{
		fscanf(fp, "%s %s", stu.no, stu.name);
		fscanf(fp, "%lf%lf%lf%lf", &stu.foreign, &stu.spec1, &stu.spec2, &stu.total);
		printf("%10s%8.2f\n", stu.name, stu.total);
	}
	fclose(fp);
	return;
}

文件是個結構體類型,這個結構體成員有


struct _iobuf {
	char *ptr;  //文件當前位置
	int _cnt;
	char* _base;//緩衝區首地址
	int _flag;
	int _file;//文件號
	int char_buf;
	int _bufsize;//緩衝區長度
	char *_temfname;
}_iobuf;

typedef struct _iobuf FILE;

C語言中文件是流式文件,文件是由一個一個的字節組成,文本文件每個字節對應一個字符,對於二進制文件,每個字節對應一個二進制位串。
文件指針一般打開方式下,位置指針設置在文件頭
追加打開方式下,位置指針設置在文件尾
ftell函數 feof函數檢測文件的當前位置指針
操作成功返回filepointer文件的當前位置指針,即相對於文件開頭的位移量(字節數)。否則返回-1L(L表示該常量爲長整型)
feof函數測試是不是在文件末尾

	long int n;
		n = ftell(fp);

ftell函數可以這麼使用來觀察相對於首位的偏移量。

定義文件當前位置指針
fseek函數 rewind函數 改變文件當前位置指針
void rewind(FILE filepointer)
int fseek(FILE
filepointer,long offset,int origin)
offset是指針偏移量,origin是起始位置
操作成功就返回0,不成功返回非0
需要注意origin

SEEK_CUR  1  文件當前位置
SEEK_END  2  文件末尾
SEEK_SET  0  文件開頭

offset可以爲正可以爲負

打開文件函數
fopen();

FILE* fopen(char* filename,char* mode)//分別代表 打開文件名 打開文件方式

文件類型:

b(binary) 打開一個二進制文件
t(text) 打開一個文本文件
文件打開方式
在文件開始
r(read) //只讀方式打開一個已經存在的文件
r+(read and write) //打開文件準備讀寫
w//只寫 如果文件已經存在則覆蓋原文件
w+//創建一個新文件準備讀寫,如果文件不存在,創建這個文件準備寫數據

在文件末尾
a//以追加方式打開一個已經存在文件,不能從文件讀取數據,如果文件不存在,則創建這個文件準備寫數據
a+//打開一個文件準備讀寫,不存在則創建該文件

文件關閉
fclose函數
int fclose(FILE* filepointer).

文件讀寫操作:

int fputc(int c,FILE *filepointer)

c是要寫入的字符,該函數向filepointer文件的當前位置寫入一個ASCLL碼爲c的字符,同時將文件的位置指針指向下一個字節,寫入成功則返回寫入字節值,否則返回EOF(-1)

char* fgets(char* str, int n, FILE *filepointer);

str 是讀出的字符串 n是讀取的長度 n-1 (0~n-1),filepointer從這個文件讀字符串。
從filepointer文件的當前位置讀取長度爲n-1的字節串,在末尾加上字符串終結符‘\0’存入str所指向的內存單元,同時將文件的位置指針後移n-1個字節。
讀取成功,返回指向字符串的指針,如果讀到文件尾或者出錯返回NULL。


char str[80];
fgets(str, 15, fp);

來看代碼
這個代碼代表意思是從fp所指向的文件中讀取14個字符出來,放入str中,後面再填充‘\0’,湊齊15個字符。
格式化的方式讀寫:
fscanf fprintf
不同點在於這兩個函數規定了格式要求
例如:

fscanf(fp, "%s %s", stu.no, stu.name);

二進制當時進行文件讀寫

fread 和 fwrite函數

size_t fread( void *buffer, size_t size, size_t count, FILE *stream );

buffer是數據存儲位置, size是數據所佔字節數, n是寫入n個數據 filepointer是從這個文件讀。
fwrite和這個一樣
我們來看幾個程序的實例
如何將一個文件的內容拷貝到另一個文件中

void copy(char fileS[], char fileT[])
{
	char ch;
	FILE *fpSource, *fpTarget;
	if ((fpSource = fopen(fileS, "r")) == NULL)
	{
		printf("打開失敗\n");
		exit(1);
	}
	if ((fpTarget = fopen(fileT, "w")) == NULL)
	{
		printf("打開失敗\n");
		exit(1);
	}
	while (!feof(fpSource))
	{
		ch = fgetc(fpSource);
		fputc(ch, fpTarget);
	}
	fclose(fpSource);
	fclose(fpTarget);
	printf("文件複製成功");
}

來看一下二進制文件的寫入


void saveToFile(struct studentType stud[], int num)
{
	FILE * fp;
	int i;
	if ((fp = fopen("stu.dat", "wb")) == NULL)
	{
		printf("cannot open file");
		return;
	}
	for (i = 0; i < num; i++)
	{
		if (fwrite(&stud[i], sizeof(struct studentType), 1, fp) != 1)
		{
			printf("file write error\n");
		}
	}
	fclose(fp);
}

再來看二進制文件的讀取

void readFromFile()
{
	struct studentType stud[];
	int i;
	FILE* fp;
	if ((fp = fopen("stu.dat", "rb")) == NULL)
	{
		printf("cannot open file");
		return ;
	}
	while (!feof(fp))
	{
		if (fread(&student, sizeof(struct studentType), 1, fp) == 1)
		{
			printf("%-10s%4d,%4d%-15s\n", student.name, student.num, student.age, student.addr);
		}
	}
	fclose fp;
}

以下就是文件的基本使用

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