我們經常見到的文件寫入和讀取。
#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;
}
以下就是文件的基本使用