C语言程序设计第六章 磁盘数据存储
——————————————————————————
——————————
济南大学第六章 磁盘数据存储
6.1 将数据写入文件
6.2 文件读 /写函数分类
6.3 文件定位函数
6.1 将数据写入文件例 6.1 将一串字符 'a'— 'z'写入文件保存起来。
#include <stdio.h>
void main( )
{
char ch;
FILE *fp;
fp=fopen("letter.txt","w");
if (fp==NULL)
{ printf("\nOpenning file error.\n");
exit(0);
}
for (ch='A';ch<='Z';ch++)
fputc(ch,fp);
fputc('\n',fp);
fclose(fp);
}
/* 定义文件指针,文件操作的步骤 1 */
/* 新建并打开文件,文件操作的步骤 2 */
/* 判断文件打开成功 */
/* 将数据写入文件,文件操作的步骤 3 */
/* 关闭文件,文件操作的步骤 4 */
文件操作的步骤:
⑴ 定义文件类型指针文件类型 FILE在头文件 stdio.h中声明
⑵ 打开文件使用文件,不论是写入数据还是读出数据,不论是对一个已有的文件进行读写还是对新文件进行操作,首先都是使用 fopen()
函数打开文件。
⑶ 向文件写入数据,或从文件读取数据写入和读取的数据方式不同,需使用不同的读写文件函数;
这是最关键的一步。
⑷ 关闭文件使用完毕必须关闭文件,才能彻底的将文件缓冲区的数据写入文件,并释放系统分配的文件缓冲区。
一、文件类型指针文件类型指针的定义格式为:
FILE *指针变量名 ;
注意,
1,只有通过文件指针变量才能调用相应的文件
2,有 n个文件就要定义 n个文件指针变量,分别对应各个文件
3,FILE必须大写如,FILE *fp;
二、文件的打开( fopen函数)
1,fopen函数的使用格式:
FILE *fp;
fp=fopen(文件名,打开方式 );
例,FILE *fp;
fp = fopen("a.txt","w" );
打开方式是指对该文件进行什么操作。
2,文件的打开方式:
使用方式 含义 文件类型 说 明
"r" 只读 文本文件 为从文件中读出数据而打开文件
"w" 只写 文本文件 为往文件中写入数据而打开文件
"a" 追加 文本文件 为向文件尾部增加数据而打开文件
"r+" 读写 文本文件 为读 /写而打开文件
"w+" 读写 文本文件 为读 /写而建立一个新文件
"a+" 读写 文本文件 为读 /写而打开文件
"rb" 只读 二进制文件 为从文件中读出数据而打开文件
"wb" 只写 二进制文件 为往文件中写入数据而打开文件
"ab" 追加 二进制文件 为向文件尾部增加数据而打开文件
"rb+" 读写 二进制文件 为读 /写而打开文件
"wb+" 读写 二进制文件 为读 /写而建立一个新文件
"ab+" 读写 二进制文件 为读 /写而打开文件
fp=fopen("student.dat","r"); fp=fopen("score.dat","wb+");
3、说明:
①、用 "r"方式打开的文件,只能读出数据而不能往文件中写数据;
而且要求文件已经存在,不能打开一个并不存在的文件,否则出错
②,用 "w"方式打开的文件,只能用于往文件中写数据而不能读取数据。
如果指定的文件不存在,则以指定的文件名建立新文件;
如果指定的文件存在,在打开文件的同时删除文件中已有的数据
③,用 "a"方式打开文件时,指定的文件一定要存在,否则出错;且只能往文件中写数据,不能读取数据;自动将数据写入文件末尾;
④,用 "r+","w+","a+"方式打开的文件,可以用来进行读 /写数据;
用 "r+"方式打开文件时,该文件应该已经存在;
用 "w+"方式时则建立一个新文件,可以先向文件写数据,然后可以读文件中的数据;
用 "a+"方式打开文件时,可以向文件追加数据,也可以从文件读取数据;
⑤,如果文件打开时出错,如:
用 "r"方式打开一个并不存在的文件;
写文件时磁盘有写保护;
磁盘已满无法建立新文件等此时 fopen函数将返回空指针 NULL,否则返回与指定文件相对应的文件指针常用下面的方法打开文件:
if ((fp=fopen("score.dat","r"))==NULL)
{ printf("Cannot open file!\n");
exit(0);
}
或:
fp=fopen("score.dat","r");
if (fp==NULL)
{ printf("Cannot open file!\n");
exit(0);
}
说明,exit函数的作用是关闭所有文件,结束程序注意,使用 exit函数要包含头文件 <stdlib.h>
⑥,以文本方式和二进制方式打开文件的区别:
其存储形式有所不同,ASCII码文件(文本文件)的每个字节存放一个 ASCII码,代表一个字符,因而便于对字符进行逐个处理(如字符串)。 ASCII码文件可以阅读,可以打印,但是它与内存数据交换时需要转换。
二进制文件是将内存中的数据按照其在内存中的存储形式原样输出,并保存在文件中。内存数据和磁盘数据交换时无须转换
,但是二进制文件不可阅读、打印。
三、关闭文件函数 fclose
使用完一个文件后应该将它关闭,使文件指针变量不再指向该文件(此后不能再通过该指针对文件进行读 /写操作)
fclose的函数原型为:
int fclose(FILE *fp)
返回值:若正常关闭,返回 0;若关闭失败,返回非 0
例,fp=fopen("file.c","r");
… …
fclose(fp);
关闭文件的重要性:
写文件时,在 "输出缓冲区 "装满后,才将数据一起写入文件。当程序结束时,缓冲区可能还未满,如未关闭文件就结束程序,则缓冲区的数据不能写入文件,会丢失数据。使用 fclose函数,不论缓冲区是否已满,都会将缓冲区的数据写入文件,再关闭文件。
四、检测文件是否结束函数 feof
作用:检测对 fp所指向文件的操作是否已经达到了文件尾部
feof的函数原型为:
int feof(FILE *fp)
返回值,非 0表示已到文件尾部; 0表示未到文件尾部例:
while (!feof(fp))
{ …… }
6.2 文件读写分类函数
1、字符读写函数
⑴ fputc()函数,int fputc(char ch,FILE *fp)
作用:将 ch中的字符输出到 fp所指向的文件中返回值:输出成功则返回 所输出的字符,失败则返回 EOF
通常,fputc函数用于往文本文件中写入一个字符。
例,FILE *fp;
char ch;
if ((fp=fopen("file1.txt","w"))==NULL)
{ printf("Can not open this file!\n");
exit(0);
}
fputc('s',fp); /*将字符 's'写入 fp指向的文件 file1.dat*/
ch=getchar( );
fputc(ch,fp); /*将变量 ch中的字符写入文件 file1.dat*/
⑵ fgetc()函数,int fgetc(FILE *fp)
作用:从 fp所指向的文件中读入一个字符返回值:返回 所读的字符,如发生错误或读到文件结束符则返回 EOF
通常,fgetc函数用于从文本文件中读取单个字符。
… …
ch=fgetc(fp);
while (ch!=EOF)
{ putchar(ch); ch=fgetc(fp); }
注意,EOF实际是一个符号常量,其值为 –1,一般用 EOF作字符文件的文件结束符
2、字符串读写函数
⑴ fgets函数格式,fgets(str,n,fp)
说明,str--字符数组名,n--整数值,fp--文件指针变量作用,从 fp所指向的文件中读 (n-1)个字符,将它们存放到 str数组中,并在其后自动加一个 '\0',如果读入 (n-1)个字符前遇到换行符或文件结束符 EOF,则结束读入。
函数返回值:成功返回 str数组的首地址,失败返回 NULL
⑵,fputs函数格式,fputs(str,fp)
说明,str:字符串常量 或 字符数组名 或 字符指针变量
fp--文件指针变量作用,将 str字符串写到 fp所指向的文件中,但 '\0'不写入函数返回值,成功返回 0,出错返回非 0值例,从键盘输入一行字符,以 '\n'结束,将这行字符保存到磁盘文件
"d:\test.txt"中。
#include <stdio.h>
#include <stdlib.h>
void main( )
{ FILE *fp;
char str1[30],str2[30];
if ((fp=fopen("d:\\test.txt","w"))==NULL)
{ printf("can not open this file!\n");
exit(0);
}
gets(str1);
fputs(str1,fp);
fclose(fp);
fp=fopen("d:\\test.txt","r");
fgets(str2,20,fp);
puts(str2);
fclose(fp);
}
3,"数据块 "读写函数格式,fread(buffer,size,count,fp)
fwrite(buffer,size,count,fp)
说明:
(1) buffer,是一个地址;通常是一个数组名对 fread而言,buffer是从文件中读取的数据要存放的存储区的首地址对 fwrite,buffer是向文件中写入数据时存储变量的地址
(2) size,要读写数据所占用的字节数
(3) count,要读写数据项的个数
(4) fp,文件指针变量注意,用 fread,fwrite 必须采用二进制方式打开文件例,从键盘输入 10个整数,把它们保存到文件,datafile”中,再从文件中读取这些整数,并输出到显示器上。
#include <stdio.h>
#include <stdlib.h>
void main( )
{
FILE *fp;
int m,n,j;
if ((fp=fopen("datafile.txt","wb+"))==NULL)
{ printf("Can not open this file!\n"); exit(0); }
for (j=0;j<10;j++)
{ scanf("%d",&m);
fwrite(&m,2,1,fp);
}
rewind(fp);
for (j=0;j<10;j++)
{ fread(&n,2,1,fp);
printf("%4d",n);
}
fclose(fp);
}
4、格式化输入输出函数
fprintf ( 文件指针变量,格式字符串,输出表列 ) ;
fscanf ( 文件指针变量,格式字符串,输入表列 ) ;
例,#include <stdio.h>
#include <stdlib.h>
void main ( )
{
FILE *fp;
int a,b,c,d;
if ((fp=fopen("exfile.txt","wb+"))==NULL)
{ printf("Can not open this file!\n");
exit(0);
}
scanf("%d%d",&a,&b);
fprintf(fp,"%d,%d\n",a,b);
rewind(fp);
fscanf(fp,"%d,%d",&c,&d);
printf("%d,%d\n",c,d);
fclose(fp);
}
6.3 文件定位函数一,rewind函数
void rewind(FILE *fp)
作用,使位置指针重新返回文件的开头返回值:无二,位置指针随机移动函数 fseek
所谓 随机读写,是指读完上一个字符后,并不一定要读写其后继的字符,而可以读写文件中任意所需的字符。
int fseek(FILE *fp,long offset,int base)
作用:将 fp所指向文件的位置指针,移到以 base所指的位置为起始点、以 offset为位移量的位置,同时清除文件结束标志返回值:定位成功则返回非 0,否则返回 0
int fseek(FILE *fp,long offset,int base)
说明:
①,起始点 base可以是,SEEK_SET,SEEK_CUR、
SEEK_END三个符号常量,其值分别为 0,1,2;分别表示文件开始、文件当前位置、文件末尾;
②,位移量 offset表示以起始点为基准,向前或向后移动的字节数 (为正表示向文件尾部的方向的移动,为负则表示向文件头部的方向移动);要求在数字后面加一个字母,L”,
表示是长整型数。
例,①,fseek(fp,2L,SEEK_SET);
将文件位置指针 从文件开始处 向后移动 2个字节
fseek(fp,2L,0)
②,fseek(fp,2L,SEEK_CUR);
将文件位置指针 从当前位置 向后移动 2个字节
fseek(fp,2L,1)
③,fseek(fp,-5L,SEEK_END);
将文件位置指针 从文件末尾 向文件头部的方向移动 5个字节
fseek(fp,-5L,2)
T h e E n d