• 简单方便用法:

读:freopen('a.txt','w',stdin);

写:freopen('b.txt','r', stdout) 

文件是存储在某种长期储存设备(磁盘、光盘等)上的一段数据流。C++把文件看成一个有序的字节流,每个文件都以文件结束标志(EOF)结束。下图是包含n个字节的文件内容。

磁盘文件由操作系统中的文件系统统一管理,也只有文件系统才能直接操作文件。所以编写C++程序来操作文件实际上是需要调用文件系统的接口函数来进行,我们学习文件的操作也就是学习一些C++库中提供的函数。是不是感觉好简单啊:-)

C++文件的操作一般分为三个步骤:打开文件读写文件关闭文件

  • 打开文件:打开文件后,操作系统为文件建立一个文件控制结构(文件控制块),并在内存中建立一个缓冲区,该缓冲区的数据对应文件的数据,之后的文件读写操作实际上是在缓冲区中进行;
  • 读写文件:通过文件控制块实现文件的输入输出;
  • 关闭文件:将文件缓冲区中的数据写回到磁盘文件中,并释放文件控制块。

C++进行文件操作时将文件分为文本文件二进制文件

  • 文本文件是可以用任何文字处理程序阅读和编辑的简单ASCII文件。
  • 二进制文件一般含有特殊的格式或计算机代码,如图形文件和可执行文件等。

FILE结构操作文件是C语言提供的文件操作方式,只要包含头文件"stdio.h"就能使用文件操作的相关函数。如下面的程序可以打开一个文件用于读:

#include <stdio.h>

FILE *fp = fopen("a.txt","r"); // 打开一个供读取数据的文件a.txt。

其中:fopen"stdio.h"提供的文件打开函数,其第一个参数是拟打开文件的路径和名字,可以包含相对路径或者绝对路径,如上面程序中就是打开当前目录下的a.txt文件。第二个参数是打开方式,fopen函数可以使用的打开方式如下表:

如果文件打开成功,函数fopen将返回一个指向FILE结构的指针,该指针指向的FILE结构管理了被打开的那个文件。如果文件打开失败(如打开一个不存在的文件用于读),那么该函数将返回NULL。上面的程序将返回值赋值给FILE*的指针fp,之后就可以通过fp来操作打开的文件了。

  • 从文本文件中读取一个字符可以使用fgetc函数:
int fgetc(FILE *stream);

// 该函数从文件指针`stream`指向的文件的当前位置读取一个字符,并以`int`类型返回。
  • 从文本文件读取一行可以使用fgets函数:
char *fgets(char *string, int n, FILE *stream);

// 该函数从文件指针`stream`指向的文件的当前位置开始读取字符串,直到遇到换行符(读入该换行符),或到达文件结束位置,或读取了`n-1`个字符。读取的字符串存入`string`所指的内存单元中,并在所有读取的字符之后添加字符串结束标记`'\0'`。如果读取成功,函数返回`string`,如果出错或读取前已经到达了文件结束的位置,将返回`NULL`。
  • 从文本文件中进行格式化读取可以使用fscanf函数
int fscanf(FILE *stream, const char *format [,argument]...);

​​​​​​​// 函数`fscanf`与`scanf`函数非常相似,只是`fscanf`函数多了一个参数`stream`以指向要读取数据的文件,该函数的功能是从指定文件中将数据按照格式控制串`format`读出并转换成相应的类型以存入对应的参数中,如果读取成功,该函数返回转换成功的参数的个数,如果出错或读取前已经到达了文件结束的位置,将返回文件结束标志`EOF`。
  • 输出格式化数据到文本文件中可以使用fprintf函数
int fprintf(FILE *stream, const char *format [,argument]…);

// 函数`fprintf`与`printf`函数相似,只是`fprintf`函数多了一个参数`stream`以表示要写入数据的文件,该函数的功能是将数据按照格式控制串`format`写入到文件指针`stream`指向的文件中,如果写入成功,函数返回写入的字节数,否则返回一个负数表示错误。
#include <stdio.h>
 
// 函数extractDigit的功能:从文件a.txt中提取数值写入文件b.txt中
void extractDigit();
 
// 请在此添加代码,实现extractDigit函数
/********** Begin *********/
 
char readADigit(FILE *fi)
{
    char c = fgetc(fi); // 从文件读取一个字符
    if(c==EOF) // 是结束符则返回
        return EOF;
    while(c>'9' || c<'0') // 如果不是数字字符,则继续读取下一个字符
    {
        c = fgetc(fi); // 读取下一个字符
        if(c==EOF) // 是结束符则返回
            return EOF;
    }
    return c; // 返回读取的数字字符
}
 
// 函数extractDigit的功能:从文件a.txt中提取数值写入文件b.txt中
void extractDigit()
{
    FILE *fi = fopen("a.txt","r"); // 以读的方式打开文件a.txt
    FILE *fo = fopen("b.txt","w"); // 以写的方式打开文件b.txt
    if(fi==NULL || fo==NULL) // 如果某个文件打开失败,则返回
        return;
    char c;
    int num=0,k=0;
    c = readADigit(fi); // 读取一个数字字符
    while(c!=EOF)
    {
        num=num*10+c-'0'; // 计算数字字符构成的整数
        k++;
        if(k==3) // 已经三位了
        {
            fprintf(fo,"%d ",num); // 将计算的整数写入文件指针fo指向的文件
            k=0; // 重新计数
            num=0; // 重新计算
        }
        c = readADigit(fi); // 读取下一个数字字符
    }
    if(k!=0) // 如果有不到三位的数值,则写入文件b.txt
    {
        fprintf(fo,"%d ",num);
    }
    fclose(fi); // 关闭文件fi
    fclose(fo); // 关闭文件fo
}
/********** End **********/

qi_gai Blogger