一.解释一些问题
1.标准输入文件(sdtin),通常对应终端的键盘。
2.标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件
都对应终端的屏幕。
(解释:File *fp=fopen()
stdin,stdout,stderr就是这个fp,不过他是随着计算机系统的开启默认打开的,其中0就是stdin,表示输入流,指从键盘输入,1代表stdout,2代表stderr,1,2默认是显示器。stdin是标准库stdio.h中定义的一个全局变量。)
3.语句freopen(“in.txt”, “r”, stdin); 就是把标准输入流stdin重定向到in.txt文件中,这样用scanf输入时,不会从键盘读取数据,而是从in.txt文件中获取输入。
(说明:在freopen(“in.txt”, “r”, stdin);中,in.txt文件应放在所建立的工程文件夹下。)
4.系统给每个打开的文件都在内存中开辟一个区域,用于存放文件的有关信息(如文件名、文件位置、文件状态等)。这些信息保存在一个结构类型变量中,该结构类型由系统定义、取名为FILE,放在“stdio.h”文件中。
注意:结构类型名“FILE”必须大写。
5.fopen
用于打开文件并返回文件指针,而freopen
用于重新定向文件流到指定文件。fopen
是打开文件的操作,而freopen
是重新定向文件流的操作。
二.文件的打开方式
1.“r” 以只读方式,打开文本文件。
“w” 以只写方式,创建并打开文本文件,已存在的文件将被覆盖。
“a” 以只写方式打开文本文件,向尾部追加数据。
“+” 与上面的字符串组合,表示以读和写的方式打开文本文件。(注意rewind的运用)
“b” 与上面的字符串组合,表示打开二进制文件。
2.
FILE *fp; // 定义文件指针
fp = fopen("f1.txt", "r"); // 打开文件
fopen( )的返回值是一个文件指针
(第一个引号中表示文件名,可包含路径和文件名;第二个引号中表示文件打开方式)
3.
fclose( fp ); /* 关闭文件 */
用来关闭一个由函数fopen( )打开的文件
(函数fclose()返回一个整型数。当文件关闭成功时,返回0值,否则返回一个非0值。)
4.
fp = fopen("f1.txt", "r"); // 打开文件
fscanf( fp, “%d”, &m ); // 对文件执行读操作
不是从键盘读入数据,而是从fp关联的文件中读入数据。
5.
fp = fopen("f1.txt", "w"); /* 打开文件 */
fprintf( fp, “%s”, “Hello World! ” ); /* 对文件执行写操作*/
不是将文字输出到屏幕,而是输出到fp关联的文件。
6. 格式化文件读/写函数fscanf( ) / fprintf ( )
7. 字符读/写函数fgetc ( ) / fputc ( ),读取失败时的返回值是EOF
int fgetc(FILE *stream)
参数:*stream: 文件指针,将要读取的文件流。
int fputc (int c, FILE *fp)
参数:c:字符的ASCII编码值;*fp: 文件指针,将要读取的文件流。
8. 字符串读/写函数fgets ( ) / fputs ( ),读取失败时的返回值是空指针即NULL
fgets()
函数的最大读取大小是其“第二个参数减1
”,这是由于字符串是以’\0’
为结束符的
char *fgets(char *str, int n, FILE *stream);
其中,str
是一个指向字符数组的指针,用于存储读取的字符串;n
是要读取的最大字符数(包括空字符)(不包括空字符只能读取n-1个字符);stream
是一个指向文件的指针,指定了从哪个文件流中读取。
fputs(const char *str, FILE *stream)
9. 数据块读/写函数fread( ) / fwrite ( ) 用于读写二进制文件
fwrite(数据区首地址, 每次写入的字节数, 写入次数, 文件指针);
fread(数据区首地址, 每次读取的字节数, 读取次数, 文件指针);
函数调用成功,返回值为数据个数;如果实际执行读/写的次数小于指定次数,那么返回实际的次数;如果调用失败,返回值为0。
struct student
{
char name[10] ;
int score ;
} stu , stuArr[10] ;
fwrite( &stu , sizeof(stu) , 1 , fp ) ; //将一个结构变量stu写入文件
fwrite( stuArr , sizeof(stuArr) , 1 , fp ) ; //将结构数组stuArr写入文件
fwrite( stuArr , sizeof(stuArr[0]) , n , fp ) ; //将结构数组stuArr的前n个元素写入文件
10.检测文件结束函数 feof()
函数(只适用于文本文件不适用于二进制文件)
feof()
函数用于检查文件指针所指向的文件是否已经到达了文件末尾。如果文件指针所指向的文件已经到达了文件末尾,则feof()
函数返回非零值(true);否则返回0(false)。
关于feof()函数重复输出尾行的问题
#include <stdio.h>
#include <stdlib.h>
int main()
{ int m ;
FILE *fp ;
if((fp=fopen("f1.txt", "r")) == NULL)
{
printf("File open error!\n");
exit(0);
}
while (!feof(fp))
{ fscanf( fp , "%d" , &m ) ;
printf( "%d\n" , m ) ;
}
fclose(fp) ;
return 0;
}
可以不使用feof函数
while ( fscanf( fp , "%d" , &m )!= EOF )
{
printf( "%d\n" , m );
}
或者
int a ;
fscanf(in,"");//处理那些看起来是空文件,实际上有空白字符的文件
while ( !feof(in))
{
fscanf(in ,“%d”,&a); //此处的空格,可以让指针in到达eof的位置
printf("%d\n",a);
}
三.例子
1.
#include <stdio.h>
#include <stdlib.h>
int main( )
{
int m ;
FILE *fp; // 定义文件指针
if( ( fp = fopen(“f1.txt”, “r”) ) == NULL)
{ //如果 打开文件失败
printf("File open error!\n");
exit(0);
}
fscanf( fp, “%d”, &m ); // 对文件执行读操作
printf( "%d\n" , m ) ;
if( fclose( fp ) )//当文件关闭成功时,返回0值,否则返回一个非0值.
{ //如果关闭文件失败
printf( "Can not close the file!\n" );
exit(0);
}
return 0;
}
exit(0);
的作用是终止程序的执行并返回退出码0
,表示程序正常退出。
在C语言中,break
语句通常用于终止循环语句(如for
、while
、do-while
循环)的执行(终止语句的执行),而不是用于终止整个程序的执行。
2. fread和fwrite的用法
int m ;
FILE *fp;
fp = fopen("f1.txt", "w");
scanf( "%d", &m );
fwrite( &m , sizeof(int) , 1 , fp ) ;
fclose( fp );
return 0;
如果保存文件成功,打开文件会出现乱码(二进制文件)
我们可以采取以下的方式来验证我们是否成功保存文件
int m ;
FILE *fp;
fp = fopen("f1.txt", "r");
//scanf( "%d", &m );
//fwrite( &m , sizeof(int) , 1 , fp ) ;
fread( &m ,sizeof(int),1,fp ) ;
printf( "==%d==\n",m ) ;
fclose( fp );
3. rewind的用法
rewind
函数用于将文件指针重新指向文件的起始位置,即将文件指针设置为文件的开头位置。其原型如下:
void rewind(FILE *stream);
stream
是一个指向文件的指针,指定了要操作的文件流。
rewind
函数将文件指针重新定位到文件的起始位置,这样可以重新从文件的开头处进行读取操作。通常在需要重新读取文件内容时使用 rewind
函数。
int m ;FILE *fp;
fp = fopen("f1.txt",“wb+");
scanf( "%d",&m );
fwrite(&m ,sizeof(int),1,fp);
rewind( fp);//重定位文件首函数。
fread( &m ,sizeof(int),1,fp);
printf("==%d==\n",m);
fclose( fp );
写完后需要重新定位
4.fread()和fwrite()对结构数组读写
typedef struct student//重命名结构体,STU为一个结构体类型
{
char name[10];
int score ;
}STU ;
STU stu[N] ;
for (i=0;fread(&stu[i], sizeof(STU),1,fp)!=0;i++)
fwrite( stu ,n*sizeof(stu[0]),1 ,fp);
在这行代码中,n
表示要写入文件的结构体数组stu
中元素的个数。sizeof(stu[0])
表示每个元素的大小。因此,n*sizeof(stu[0])
表示要写入的总字节数,即将n
个结构体元素写入文件。
四.拓展问题
1.输入中文后再打开文件出现乱码,将编码方式UTF-8改为ANSI