2.3 文件输入/输出函数
文件输入/输出函数指的是从文件中读取数据或向文件写入数据的函数。这些函数的操作对象都是文件。
2.3.1 fgetc函数和getc函数──从文件中读取一个字符
1.函数原型
int fgetc(FILE *stream);
int getc (FILE *stream);
2.函数功能
fgetc函数和getc函数都接受参数stream指向的文件中字符的当前位置,并将文件位置指示器移动到下一个位置。fgetc函数与getc函数功能相同。
3.函数参数
参数stream:指向要读取数据的文件。
4.函数的返回值
如果调用成功,则函数返回读取的字符;如果到达文件尾或有错误发生,则函数返回EOF。
5.函数范例
/********************************************
*范例编号:02_12
*范例说明:从文件中读取一个字符
*********************************************/
01 #include <stdio.h>
02 #include <stdlib.h>
03 void main()
04 {
05 FILE *file;
06 char ch;
07 int n=0;
08 file=fopen(“myfile.txt”,”r”);
09 if (file==NULL)
10 printf(“cannot open file!”);
11 else
12 {
13 do
14 {
15 ch=fgetc (file);
16 putchar(ch);
17 if (ch>=’a’&&ch<=’z’||ch>=’A’&&ch<=’Z’)
18 n++;
19 } while (ch!=EOF);
20 fclose (file);
21 printf (“\nThe file contains %d letters.\n”,n);
22 }
23 system(“pause”);
24 }
该函数范例的运行结果如图2-12所示。
图2-12 函数范例的运行结果
6.函数解析
(1)在对文件进行读/写之前,需要先打开文件并判断是否成功打开文件。成功打开文件后才能对文件进行读/写。
(2)在对文件进行读/写完毕之后,需要关闭文件。
2.3.2 fgets函数──从文件中读取多个字符
1.函数原型
char *fgets(char *str,int num,FILE *stream);
2.函数功能
fgets函数从stream指向的文件中最多读取num−1个字符,并存入str指向的字符数组中。在字符被读入数组后,自动在字符数组的最后添加一个空字符表示字符串的结束。
3.函数参数
(1)参数str:指向存放字符的数组。
(2)参数num:从stream指向的文件中读取字符的最大个数是num−1。
(3)参数stream:文件指针,指向要读取字符的文件。
4.函数的返回值
如果操作成功,则fgets函数返回str;否则,返回一个空指针。如果读取过程中出错,则str指向的数组中的内容是不确定的。
5.函数范例
/********************************************
*范例编号:02_13
*范例说明:从指定的文件中读取多个字符
*********************************************/
01 #include <stdio.h>
02 #include <stdlib.h>
03 void main()
04 {
05 FILE *file;
06 char str[80];
07 int i,digits=0,alpha=0,others=0;
08 file=fopen (“myfile.txt” , “r”);
09 if (file==NULL)
10 printf (“cannot open file!”);
11 else
12 {
13 fgets (str , 80 , file);
14 printf(“%s\n”,str);
15 for(i=0;i<strlen(str);i++)
16 {
17 if(str[i]>=’0’&&str[i]<=’9’)
18 digits++;
19 else if(str[i]>=’A’&&str[i]<=’Z’|| str[i]>=’a’&&str[i]<=’z’)
20 alpha++;
21 else
22 others++;
23 }
24 printf(“英文字母:%d,数字字符:%d,其他字符:%d\n”,alpha,digits,others);
25 fclose (file);
26 }
27 system(“pause”);
28 }
该函数范例的运行结果如图2-13所示。
图2-13 函数范例的运行结果
6.函数解析
(1)fgets函数一次能从指定的文件中读取多个字符。
(2)在读取文件时,使用feof函数或ferror函数检测是否有错误发生。
(3)如果stream的值是stdin,则表示接受从键盘输入的数据。
2.3.3 fprintf函数──格式化输出数据到指定的文件中
1.函数原型
int fprintf(FILE *stream,char *format[,argument]…);
2.函数功能
fprintf函数将格式化数据写入stream指向的文件中。
3.函数参数
(1)参数stream:文件指针,指向要存放数据的文件。
(2)参数format:要输出的文本,包括格式字符和普通字符。与printf函数的参数含义相同。
(3)参数argument:文件指针,指向要读取字符的文件。
4.函数的返回值
如果调用成功,则函数返回实际写入文件的字符个数;否则,返回一个负数。
5.函数范例
/********************************************
*范例编号:02_14
*范例说明:格式化输出数据到指定的文件中
*********************************************/
01 #include <stdio.h>
02 #include <stdlib.h>
03 void main()
04 {
05 FILE *fp;
06 char str1[30],str2[2],str3[30];
07 fp=fopen (“myfile.txt”,”w”);
08 if(!fp)
09 {
10 printf(“cannot open file in writting!”);
11 exit(-1);
12 }
13 fprintf (fp, “chinese:%.2f math:%.2f english:%.2f.\n”,80.5,89.5,83.5);
14 fclose (fp);
15 fp=fopen (“myfile.txt”,”r”);
16 if(!fp)
17 {
18 printf(“cannot open file in reading!”);
19 exit(-1);
20 }
21 fscanf (fp, “%s %s %s”,str1,str2,str3);
22 printf (“%s\n”,str1);
23 printf (“%s\n”,str2);
24 printf (“%s\n”,str3);
25 fclose (fp);
26 system(“pause”);
27 }
该函数范例的运行结果如图2-14所示。
图2-14 函数范例的运行结果
6.函数解析
(1)fprintf函数的作用与printf函数的类似,区别在于fprintf函数输出数据到指定的文件中,而printf函数则输出数据到屏幕上。
(2)在向文件中写数据时,以写的方式打开文件。从文件中读取数据时,以读的方式打开文件。
(3)范例02_14运行后,myfile.txt文件中存放的内容如下。
chinese:80.50 math:89.50 english:83.50.
若想查看写入的文件内容,可用fscanf函数从文件中读取数据并打印输出。
2.3.4 fscanf函数──从文件中读取格式化数据
1.函数原型
int fscanf(FILE *stream,const char *format[,argument]);
2.函数功能
fscanf函数从stream指向的文件中读取由format格式化的数据,并存入参数argument列表中。
3.函数参数
(1)参数stream:文件指针,指向读取的文件对象。
(2)参数format:格式说明,与scanf函数的参数format含义相同。
(3)参数argument:变量地址列表,用来存放读取的数据,与format指向的格式字符对应。
4.函数的返回值
如果调用成功,则函数返回实际读取的字符个数(不包括空白符);如果读取操作失败,则返回EOF。
5.函数范例
/********************************************
*范例编号:02_15
*范例说明:从指定的文件中读取格式化数据
*********************************************/
01 #include <stdio.h>
02 #include <stdlib.h>
03 void main()
04 {
05 FILE *fp;
06 float chinese,math,english;
07 fp=fopen (“myfile.txt”,”w+”);
08 if(!fp)
09 {
10 printf(“cannot open file!”);
11 exit(-1);
12 }
13 fprintf (fp, “%.2f\n”,80.5);
14 fprintf(fp,”%.2f\n”,89.5);
15 fprintf(fp,”%.2f\n”,83.5);
16 rewind(fp);
17 fscanf(fp,”%f”,&chinese);
18 fscanf(fp,”%f”,&math);
19 fscanf(fp,”%f”,&english);
20 printf(“%f,%f,%f\n”,chinese,math,english);
21 fclose (fp);
22 system(“pause”);
23 }
该函数范例的运行结果如图2-15所示。
图2-15 函数范例的运行结果
6.函数解析
(1)fscanf函数的作用与scanf函数的类似,区别在于fscanf函数从指定的文件中读取格式化数据,而scanf函数则通过键盘读取格式化数据。
(2)fscanf函数与fprintf函数经常配合使用。使用fscanf函数读取文件中的数据时,必须保证写入文件的格式与读取文件的格式一致,否则会发生读取数据错误。
2.3.5 fputc函数和putc函数──输出一个字符到指定的文件中
1.函数原型
int fputc(int ch,FILE *stream);
2.函数功能
fputc函数和putc函数的功能都是输出一个字符到指定的文件中。
3.函数参数
(1)参数ch:要写入文件的字符。
(2)参数stream:文件指针,指向字符写入的文件。
4.函数的返回值
如果调用成功,则函数返回写入文件的字符;否则,返回EOF。
5.函数范例
/********************************************
*范例编号:02_16
*范例说明:输出一个字符到指定的文件中
*********************************************/
01 #include <stdio.h>
02 #include <stdlib.h>
03 void main ()
04 {
05 FILE *fp;
06 char *str=”This is a test!”,*str0;
07 fp=fopen (“file.txt”,”w”);
08 if (!fp)
09 {
10 printf(“cannot open file!”);
11 exit(-1);
12 }
13 str0=str;
14 while(*str)
15 {
16 fputc(*str,fp);
17 putchar(*str);
18 str++;
19 }
20 printf(“\n共%d个字符!\n”,str-str0);
21 fclose (fp);
22 system(“pause”);
23 }
该函数范例的运行结果如图2-16所示。
图2-16 函数范例的运行结果
6.函数解析
fputc函数的作用与putc函数的相同,经常与fgetc函数或getc函数配合使用。
2.3.6 fputs函数──输出一个字符串到指定的文件中
1.函数原型
int fputs(const char *str,FILE *stream);
2.函数功能
fputs函数的功能是将str指向的字符串输出到stream指向的文件中。
3.函数参数
(1)参数str:一个包含’\0’的字符串,作为输入文件的数据。
(2)参数stream:文件指针,指向字符串写入的文件对象。
4.函数的返回值
如果调用成功,则返回一个非负数;否则,返回EOF。
5.函数范例
/********************************************
*范例编号:02_17
*范例说明:输出一个字符串到指定的文件中
*********************************************/
01 #include <stdio.h>
02 #include <stdlib.h>
03 void main ()
04 {
05 FILE *fp;
06 char str[256],str2[256];
07 printf(“Please input a sentence to file:\n”);
08 fgets(str,255,stdin);
09 fp=fopen(“f.txt”,”w”);
10 if(!fp)
11 {
12 printf(“Cannot open the file.\n”);
13 exit(-1);
14 }
15 fputs(str,fp);
16 fclose(fp);
17 fp = fopen (“f.txt”,”r”);
18 if (fp)
19 {
20 if (fgets (str2,100,fp) != NULL )
21 puts (str2);
22 fclose (fp);
23 }
24 system(“pause”);
25 }
该函数范例的运行结果如图2-17所示。
图2-17 函数范例的运行结果
6.函数解析
fputs函数与fgets函数配合使用。fputs函数将字符串写入指定的文件,但不写入字符串的结束标志’\0’。
2.3.7 fread函数──从文件中读取一个数据块
1.函数原型
int fread(void *buffer,int size,int count,FILE *stream);
2.函数功能
fread函数从stream指向的文件中读取count个字段,每个字段的大小均为size个字节,将其存放到buffer指向的字符数组中。
3.函数参数
(1)参数buffer:字符数组或指针,存放从文件中读取的数据。
(2)参数size:每个字段的大小,单位为字节。
(3)参数count:字段的个数,每个字段的大小均为size个字节。
(4)参数stream:文件指针,指向读取数据的文件对象。
4.函数的返回值
函数返回实际读取的字段个数。如果读取的字段个数小于函数指定的字段大小,则可能发生了错误,或者是文件位置指针到了文件末尾。
5.函数范例
/********************************************
*范例编号:02_18
*范例说明:从指定的文件中读取一个数据块
*********************************************/
01 #include <stdio.h>
02 #include <stdlib.h>
03 void main()
04 {
FILE *fp,
05 char str[30],word[27];
06 int i,n;
07 for(i=0;i<26;i++)
08 word[i]=’A’+i;
09 if( (fp=fopen( “myfile.dat”, “wb” ))!=NULL )
10 {
11 n=fwrite( word, sizeof( char ), 26, fp );
12 printf( “Write %d items successfully!\n”, n );
13 fclose( fp );
14 }
15 else
16 printf( “Cannot open the file to write.\n” );
17 if( (fp=fopen( “myfile.dat”, “rb” ))!=NULL )
18 {
19 n=fread( str, sizeof( char ), 26, fp );
20 printf( “Number of items:%d\n”, n );
21 printf( “Contents of buffer:%.26s\n”, str );
22 fclose( fp );
23 }
24 else
25 printf( “Cannot open the file to read.\n” );
26 system(“pause”);
27 }
该函数范例的运行结果如图2-18所示。
图2-18 函数范例的运行结果
6.函数解析
(1)fread函数既可以读取文本文件中的数据,也可以读取二进制文件中的数据。而fgetc函数、fgets函数都是从文本文件中读取数据。
(2)fread函数与fwrite函数配合使用。
(3)实际上,fread函数以二进制的方式读取文件中的数据,因此,不能读取手工录入文本文件中的数据。要读取文件中的数据,必须用fwrite函数写入。
2.3.8 fwrite函数──向文件中写入数据块
1.函数原型
int fwrite(void *buffer,int size,int count,FILE *stream);
2.函数功能
fwrite函数将buffer指向的数组中的字符写入stream指定的文件中。写入数据的长度是count×size。
3.函数参数
(1)参数buffer:字符数组或字符指针,指向要写入文件的字符数组。
(2)参数size:字段的大小,单位是字节。
(3)参数count:字段的个数,每个字段的大小均为size个字节。
(4)参数stream:文件指针,指向写入文件的对象。
4.函数的返回值
如果调用成功,则函数返回实际写入文件的字段个数。如果函数中指定的字段个数与实际写入的字段个数不同,则说明有错误发生。
5.函数范例
/********************************************
*范例编号:02_19
*范例说明:向文件中写入数据块
*********************************************/
01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <string.h>
04 #define MAXSIZE 100
05 void main()
06 {
07 FILE *fp;
08 char str1[]=”I am a C Programmer, Now work in Beijing!”,str2[MAXSIZE];
09 int numread, numwritten;
10 if( (fp=fopen( “myfile.dat”, “wb” ))!=NULL )
11 {
12 numwritten=fwrite( str1, sizeof( char ), strlen(str1), fp );
13 printf( “Write %d items successfully!\n”, numwritten );
14 fclose( fp );
15 }
16 else
17 printf( “Cannot open the file to write.\n” );
18 if( (fp=fopen( “myfile.dat”, “rb” ))!=NULL )
19 {
20 numread=fread( str2, sizeof( char ), numwritten, fp );
21 str2[numwritten]=’\0’;
22 printf( “Amount:%d\n”, numread );
23 printf( “Contents:%s\n”,str2);
24 fclose( fp );
25 }
26 else
27 printf( “Cannot open the file to read.\n” );
28 system(“pause”);
29 }
图2-19 函数范例的运行结果
该函数范例的运行结果如图2-19所示。
6.函数解析
(1)fread函数既可以读取文本文件中的数据,也可以读取二进制文件中的数据。而fgetc函数、fgets函数都是从文本类型的文件中读取数据。
(2)fread函数与fwrite函数经常配合使用。
(3)fread函数实际上以二进制的方式读取文件中的数据,因此,不能读取手工写入的数据。要读取文件中的数据,必须用fwrite函数写入。
2.3.9 vfprintf函数──输出格式化数据到指定的文件
1.函数原型
int vfprintf(FILE *stream,const char *format,va_list arg);
2.函数功能
vfprintf函数根据format字符串格式化数据,并将该数据输出到stream指向的文件中。
3.函数参数
(1)参数stream:文件指针,指向输出的文件对象。
(2)参数format:格式说明,要写入stream中的文本,包括参数列表中经过格式化的数据。参数format的含义与printf函数的参数含义相同。
(3)参数arg:可变参数列表,指向要格式化的参数。
4.函数的返回值
如果调用成功,则函数返回实际输出的字符个数;否则,返回一个负数。
5.函数范例
/********************************************
*范例编号:02_20
*范例说明:输出格式化数据到指定的文件
*********************************************/
01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <stdarg.h>
04 void PrintFormatted (FILE *stream, char *format, ...)
05 {
06 va_list args;
07 va_start (args, format);
08 vfprintf (stream, format, args);
09 va_end (args);
10 }
11 void main ()
12 {
13 FILE *fp;
14 fp=fopen (“myfile.txt”,”w”);
15 if(!fp)
16 {
17 printf(“cannot open the file.\n”);
18 exit(-1);
19 }
20 PrintFormatted (fp,”name:%s.\n”,”周杰”);
21 PrintFormatted (fp,”chinese:%d.\n”,87);
22 PrintFormatted (fp,”math:%f.\n”,91.5);
23 fclose (fp);
24 system(“pause”);
25 }
该函数范例生成的文件myfile.txt中的内容如下。
name:周杰.
chinese:87.
math:91.500000.
6.函数解析
vfprintf函数与fprintf函数功能相同,都是将变参数列表arg中的数据格式化并输出到指定的文件中。
2.3.10 vfscanf函数──从文件中读取格式化数据
1.函数原型
int vfscanf(FILE *stream,const char *format,va_list arg_list);
2.函数功能
vfscanf函数从stream指定的文件中读取格式化数据到可变参数列表arg_list中。
3.函数参数
(1)参数stream:文件指针,指向输出的文件对象。
(2)参数format:格式说明,要写入stream中的文本,包括格式化参数列表中的数据。参数format的含义与printf函数的参数含义相同。
(3)参数arg_list:可变参数列表,接受格式化的数据。
4.函数的返回值
如果调用成功,则函数返回实际读入数据的参数个数;否则,返回EOF。
5.函数范例
/********************************************
*范例编号:02_21
*范例说明:从文件中读取格式化数据
*********************************************/
01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <stdarg.h>
04 int ReadFormatted(FILE *stream,char *format, ...)
05 {
06 va_list args;
07 int cnt;
08 va_start(args, format);
09 cnt=vfscanf(stream, format, args);
10 va_end(args);
11 return(cnt);
12 }
13 void main()
14 {
15 FILE *fp;
16 int i=20;
17 float f=115.5;
18 char s[]=”nwu”;
19 fp =fopen(“myfile.txt”,”w”);;
20 if (fp==NULL)
21 {
22 printf(“cannot open file.”);
23 exit(-1);
24 }
25 fprintf(fp,”%d %f %s\n”,i,f,s);
26 rewind(fp);
27 ReadFormatted(“%d %f %s”,&i,&f,s);
28 printf(“%d %f %s\n”,i,f,s);
29 fclose(fp);
30 }
该函数范例的运行结果如图2-20所示。
图2-20 函数范例的运行结果
6.函数解析
vfscanf函数结合了scanf函数与vscanf函数的特点。
vfscanf函数与scanf函数的区别:vfscanf函数用可变参数表指针接受读入的数据,而scanf函数用变量接受读入的数据。
vfscanf函数与vscanf函数的区别:vfscanf函数从指定的文件中读取数据,而vscanf函数从键盘读取数据。当vfscanf函数中的stream参数为stdin时,两者作用相同,即vfscanf(stdin,char* format,va_list arg_list)与vscanf函数等价。