1.fputc函数
把一个字符写到磁盘文件上去。其一般调用形式为
fputc(ch,fp);
其中ch是要输出的字符,它可以是一个字符常量,也可以是一个字符变量.fp是文件指针变量。fputc(ch,fp)函数的作用是将字符(ch的值)输出到fp所指向的文件中去。fputc函数也带回一个值,如果输出成功则返回值就是输出的字符;如果输出失败,则返回一个EOF(-1),EOF是在stdio.h文件中定义的符号常量,值为一1.
putchar函数,其实putchar是从fputc函数派生出来的。putchar(c)是在stdio.b文件中用预处理命令#define定义的宏:
##define putchar (c) fputc(c,srdout)
前面已叙述,stdout是系统定义的文件指针变量,它与终端输出相连。fputc(c,stdout)的作用是将c的值输出到终端。用宏putchar(c)比写fputc(c ,stdout)简单一些。从用户的角度,可以把putchar(c)看作函数而不必严格地称它为宏。
2.fgetc 函数
从指定的文件读人一个字符,该文件必须是以读或读写方式打开的。fgetc函数的调用形式为
ch=fgetc(fp);
fp为文件型指针变量,ch为字符变量。fgetc函数带回一个字符,赋给ch。如果在执行 fgetc函数读字符时遇到文件结束符,函数返回一个文件结束标志EOF(即一1)。如果想从一个磁盘文件顺序读入字符并在屏幕上显示出来,可以:
ch=fgetc (fp);
while (ch!=EOF)
{putchar(ch);
ch=fgetc(fp);
}
注意:EOF不是可输出字符,因此不能在屏幕上显示。由于字符的ASCII码不可能出现 -1,因此EOF 定义为一1是合适的。当读入的字符值等于一1(即EOF)时,表示读入的已不是正常的字符而是文件结束符。但以上只适用于读文本文件的情况。现在ANSIC已允许用缓冲文件系统处理二进制文件,而读入某一个字节中的二进制数据的值有可能是 -1,而这又恰好是EOF的值。这就出现了需要读入有用数据而却被处理为“文件结束”的情况。为了解决这个问题,ANSIC提供一个feof函数来判断文件是否真的结束。feof(fp)用来测试fp所指向的文件当前状态是否“文件结束”。如果是文件结束,函数feof (fp)的值为1(真),否则为0(假)。
如果想顺序读人一个二进制文件中的数据,可以用
while(!feof(fp))
{lc-- fgetc (fp):
.
.
.
}
当未遇文件结束,feof(fp)的值为0.! feof(p)为1,读入一个字节的数据赋给整型变量c并接着对其进行所需的处理.直到遇文件结束,feof(fp)值为1,!eof(fp)值为0.不再执行 while 循环.
这种方法也适用于文本文件。
3.fputc和 fgetc 函数使用举例
在掌握了以上几种函数以后,可以编制一些简单的使用文件的程序。
例13.1从键盘输入一些字符,逐个把它们送到磁盘上去,直到输人一个“#"为止。
# include <stdio.h>
main()
{FILE*fp;
char ch,filename[10];
scanf("%s", filename ):
if ((fp=fopen (filename,"w"))==NULL)
{printf("cannot open file\n" ) ;
exit(0);}
ch=getchar(); *此语句用来接收在执行scanf语句时最后输人的回车符/
ch=getchar( ); /*接收输入的第一个字符/
while(ch!='#')
{
fputc(ch,fp);putchar(ch);
ch=getchar();
}
fclose (fp);
}
运行情况如下:
file1.c (输入磁盘文件名)
computer and c#↙ (输人一个字符串)
computer and c (输出一个字符串)
文件名由键盘输入,赋给字符数组filename,fopen函数中的第一个参数“文件名”可以直接写成字符串常量形式(如"file1.c"),也可以用字符数组名,在字符数组中存放文件名(如本例所用的方法)。本例运行时,从键盘输入磁盘文件名“file1.c”,然后输入要写入该磁盘文件的字符“computer and c",“#”是表示输人结束,程序将“computer and c”写到以“filel.c”命名的磁盘文件中,同时在屏幕上显示这些字符,以便核对。
可以用 DOS 命令将 filel.c文件中的内容打印出来:
- type file1.c
computer and c
证明了在filel.c文件中已存入了“computer and c"的信息。
例13.2 将一个磁盘文件中的信息复制到另一个磁盘文件中。
# include <stdio.h>
main()
{FILE * in,* out;
char ch,infile[10],outfile[10];
printf("Enter the infile name:\n" );
scanf("%s", infile);
printf("Enter the outfile name:\n");
scanf("%s",outfile);
if( (in=fopen (infile,"r"))==NULL)
{printf("cannot open infile\n");
exit(0);
}
if((out=fopen (outfile,"w"))==NULL)
{printf("cannot open outfile\n");
exit(0);
}
while(!feof(in))fputc(fgetc (in),out);
fclose(in);
fclose(out);
}
运行情况如下:
Enter the infile name:
file1.ck (输入原有磁盘文件名)
Enter the outfile name:
file2.c (输入新复制的磁盘文件名)
程序运行结果是将filel.c文件中的内容复制到file2.c中去。可以用下面DOS命令验证
c>type file1.c
computer and c (file1.c 中的信息)
c>type file2.c
computer and c (file2.c中的信息)
以上程序是按文本文件方式处理的。也可以用此程序来复制一个二进制文件,只需将两个fopen函数中的“r”和“w”分别改为“rb”和“wb”即可。
也可以在输入命令行时把两个文件名一起输入。这时要用到main函数的参数。程序可改为
#include <stdio.h>
main (int arge,char * argv[ ])
{FILE*in.out;
char ch;
if (arge!=3)
{printf(“You forgot to enter a filename\n");
exit(0);
}
if ((in=fopen(argv[1]."r"))=-NULL)
{printf (" cannot open infile\n" );
exit(0);
}
if ((out=fopen(argv[2],"w"))==NULL)
{printf("cannot open outfile\n" );
exit(0);
}
while (! feof (in))fputc (fgetc (in),out);
fclose(in);
fclose(out );
}
假若本程序的源文件名为a.c,经编译连接后得到的可执行文件名为a.exe,则在 DOS 命令工作方式下,可以输入以下的命令行:
C>a file.c file2.c
即在键人可执行文件名后,再输入两个参数file1.c和 file2.c,分别输入到argv[1]和argv[2]中,argv[0]的内容为a,argc 的值等于3(因为此命令行共有3个参数)。如果输人的参数少于3个,则程序会输出:“你忘了输入一个文件名”。程序执行结果是将filel.c中的信息复制到file2.c中。可以用以下命令验证:
- type file1.c
computer and c
(这是 file1.c文件中的信息)
- type file2.c
- computer and c
(这是file2.c文件中的信息。可见filel.c已复制到 file2.c中了)。
最后说明一点,为了书写方便,系统把fputc 和 fgetc 定义为宏名 putc 和getc;
#define putc (ch,fp)fpute (ch,fp)
# define gete(fp)fgetc (fp)
这是在 stdio.h 中定义的。因此,用putc和 fputc 及用 getc 和fgetc是一样的。一般可以把它们作为相同的函数来对待。