C语言的文件的操作(二)
八.数据块读写
#fread 函数是从文件中读出数据块。
int fread(void *buf, int size, int count, FILE *fp);
#fwrite函数是向文件写入数据块。
int fwrite(void *buf, int size, int count, FILE *fp);
参数:
buf是一个指针,对fread是读入数据的存放地址,对fwrite是要输出数据的地址。
size,要写的字节数;count,要进行写多少个size字节的数据项;fp,文件型指针; 指针将首地址和字节数大小长度给buf。
整块数据的读写函数用来读写一块数据,如果一个数据元素、一个数据变量的值相等。
下面的例子从键盘输入两个学生的数据,写入一个文件中,在读出这两个学生的数据,显示在屏幕上,代码如下:
/file_block_rw.cpp */
#include <stdio.h>
#include <stdlib.h>
struct student
{
char name[10];
int num;
int age;
char addr[15];
} boya[2],boyb[2], *pp, *qq;
int main(void)
{
FILE*fp;
char ch;
int i;
pp = boya;
qq = boyb;
if ((fp = fopen("studentfile ","wb+")) == NULL)
{
printf("cannot open this file !");
getchar();
exit(1);
}
printf("\n input data\n");
for(i=0; i<2; i++, pp++)
scanf("%s %d %d %s",pp->name,&pp->num,&pp->age,pp->addr);
pp = boya;
fwrite(pp, sizeof(struct stu), 2, fp);
rewind(fp);
fread(qq, sizeof(struct stu), 2, fp);
printf("\n\n name\t number age addr\n");
for(i=0; i<2; i++, qq++)
printf("%s\t %5d %7d %s\n",qq->name,qq->num,qq->age,qq->addr);
fclose(fp);
return 0;
}
说明:本例程序中定义了一个数据结构student,说明了两个结构数据组boya和boyb,以及两个结构指针变量pp和qq。pp指向boya,qq指向boyb。然后以读写方式打开二进制文件studentfile,输出两个学生数据之后,写入该文件中,然后把文件内部位置指针移到文件首,读出两块学生数据后,在屏幕上显示出来。
假设有如下结构体:
struct student_type
{
char name[10];
int num;
int age;
char addr[30];
}stud[40];
假设,用for语句和fwrite函数可以将内存中的学生数据输出到磁盘文件中去:
for(i=0;i<40;i++)
fwrite(&stud[i],sizeof(struct student_tpye),1,fp);
同样的以上学生数据已存放在磁盘文件中,可以用下面for语句和fread函数读入40个学生的数据到内存中:
for(i=0;i<40;i++)
fread(&stud[i],sizeof(struct student_tpye),1,fp);
如果fread或fwrite函数调用成功,则函数返回值为count的值,即输入或输出数据项的完整个数。
九.格式化读写
#fscanf函数的功能是按指定的格式从一个流中执行格式化输入。
int fscanf(FILE *fp, char *format,…);
fscanf(文件指针,格式字符串,输出表列);
#fprintf函数的功能是将数据按指定的格式输出到指定文件中。
int fprintf(FILE *fp, char *format,…);
fprintf(文件指针,格式字符串,输出表列);
fprintf函数和fscanf函数和printf函数、scanf函数作用相仿,都是格式化读写函数。只有一点不同,fprintf和fscanf函数读写对象不是键盘和显示器,而是磁盘文件。其代码示例如下:
/*file_format_rw.cpp */
#include <stdio.h>
#include <stdlib.h>
struct student
{
char name[10];
int num;
int age;
char addr[15];
} boya[2],boyb[2],*pp, *qq;
int main(void)
{
FILE* fp;
char ch;
int i;
pp = boya;
qq = boyb;
if((fp=fopen("studentfile","wb+"))== NULL)
{
printf("cannot open file strike any key exit!");
getchar();
exit(1);
}
printf("\n intput data\n");
for(i=0; i<2; i++,pp++)
scanf("%s %d %d %s\n",pp->name,&pp->num,&pp->age,pp->addr);
pp = boya;
for(i=0; i<2; i++,pp++)
fprintf(fp,"%s %d %d %s\n",pp->name,pp->num,pp->age,pp->addr);
rewind(fp);
for(i=0; i<2; i++,qq++)
fscanf(fp,"%s %d %d %s\n",qq->name,&qq->num,&qq->age,qq->addr);
printf("\n\n name \t number age addr\n");
qq = boyb;
for(i=0; i<2; i++,qq++)
printf("%s\t %5d %7d %s\n",qq->name,qq->num,qq->age,qq->addr);
fclose(fp);
return 0;
}
这里采用了循环语句来读写全部数组元素。注意指针变量pp、qq由于循环改变了它们的值,因此在分别对它们重新赋予了数组的首地址。
十.随机读写
文件的定位
文件中有一个位置指针,指向当前读写的位置。如果顺序读写一个文件,每次读写一个字符,则读写完一个字符后,该位置指针自动移到下一个字符位置。如果想改变这样的规律,强制使位置指针指向其他指定的位置,可以用有关函数。
#rewind函数的作用是使位置指针重新返回文件的开头。
void rewind(FILE * stream);
函数说明 rewind()用来把文件流的读写位置移至文件开头。参数stream为已打开的文件指针。此函数相当于调用fseek(stream,0,SEEK_SET)。
# fseek()函数的功能用来移动文件内部位置指针。
int fseek(FILE * stream,long offset,int whence);
fseek(文件指针,位移量,起始点);
“文件指针” 指向被移动位置指针的文件类型指针。
“位移量” 表示移动的字节数,要求位移量是long型数据,以便在文件长度大于64KB时不会出错。当用常量表示位移量时,要求加后缀“L” 。
“起始点” 表示从何处开始计算位移量,规定的起始点有三种:文件首,当前位置和文 件尾。
其表示方法如下表。
起始点 表示符号 数字表示
文件首 SEEK_SET 0
当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2
fseek(fp, 100L, 0); 将位置指针移到离文件头100个字节处。
fseek(fp, 50L, 1); 将位置指针移到离当前位置50个字节处。
fseek(fp, -10L, 2); 将位置指针从文件末尾处向后退10个字节。
还要说明的是fseek函数一般用于二进制文件。在文本文件中由于要进行转换,故往往计算的位置会出现错误。常用fread 和fwrite 函数对文件进行随机读写。
#include <stdio.h>
#include <stdlib.h>
struct student
{
char name[10];
int num;
int age;
char addr[15];
}boy,*qq;
int main(void)
{
FILE *fp;
char ch;
int i=1;
qq=&boy;
if((fp=fopen("student","rb"))==NULL)
{
printf("Cannot open file strike any key exit!");
getchar();
exit(1);
}
rewind(fp);
fseek(fp,i*sizeof(struct stu),0);
fread(qq,sizeof(struct stu),1,fp);
printf("\n\nname\tnumber age addr\n");
printf("%s\t%5d %7d %s\n",qq->name,qq->num,qq->age,qq->addr);
return 0;
}
代码以读二进制方式打开文件,并移动文件位置指针,然后在读出的数据,即为第二个学生的数据。
另外:
C语言中常用的文件检测函数
1.文件结束检测函数 feof
# feof 函数的功能是判断文件是否处于文件结束位置,如文件结束,则返回值为1,否则
返回值为 0.
函数调用的一般
形式是: feof(文件指针);
2.读写文件出错检测函数 ferror
#ferror 函数的功能是检查文件在用各种输入输出函数进行读写时是否出错。如 ferror
返回值为 0表示未出错,否则表示有错。
ferror 函数调用格式:
ferror(文件指针);
3.文件出错标志和文件结束标志置 0 函数 clearerr
#clearerr 函数的功能是用于清除出错标志和文件结束标志,使他们为 0 值。
clearerr 函数调用格式:
clearerr(文件指针)