C语言里面对文件的操作是通过文件指针,以及一些相关的函数,那么C++中是如何对文件进行操作的呢?没错,就是通过 fstream 这个文件流来实现的。当我们使用#include 时,我们就可以使用其中的 ifstream,ofstream以及fstream 这三个类了(ofstream是从内存到硬盘,ifstream是从硬盘到内存),也就可以用这三个类来定义相应的对象了,这三个类分别代表一个输入文件,一个输出文件,以及一个输入输出文件。Ifstream类支持>>操作符,ofstream类支持<<操作符,fstream类同时支持>>和<<操作符。
函数 fopen()将一个文件和一个流关联起来,并初始化一个类型为 FILE 的对象,该对象包含了控制该流的所有信息。这些信息包括指向缓冲区的指针;文件位置指示器,它指定了获取文件的位置;以及指示错误和文件结尾情况的标志。
每个用于打开文件的函数(也就是 fopen()、freopen()和 tmpfile())都会返回一个指向 FILE 对象的指针,该 FILE 对象包含与被打开文件相关联的流。一旦打开了文件,就可以调用函数传递数据并对流进行处理。这些函数都把指向 FILE 对象的指针(通常称为 FILE 指针)作为它们的参数之一。FILE 指针指定了正在进行操作的流
FILE *fopen( const char * restrict filename,const char * restrict mode );
FILE *freopen(const char * restrict filename,
const char * restrict mode,
FILE * restrict stream );
FILE *tmpfile( void );
所有三个打开文件的函数 fopen()、freopen()和 tmpfile(),都会返回一个指针。如果成功,该指针就指向已打开的流,如果失败,该指针就为空指针
#include
#include
_Bool isReadWriteable( const char *filename )
{
FILE *fp = fopen( filename, "r+" ); // 打开一个文件以用于读写
if ( fp != NULL ) // fopen()是否执行成功
{
fclose(fp); // 成功:关闭文件,没有错误需要处理
return true;
}
else // 失败
return false;
}
关闭文件时需要使用函数 fclose()
int fclose( FILE *fp );
正常返回:0。
异常返回:EOF,表示文件在关闭时发生错误。
ofstream out("...", ios::out);
ifstream in("...", ios::in);
fstream foi("...", ios::in|ios::out);
文件写操作
// writing on a text file
#include
int main () {
ofstream out("out.txt");
if (out.is_open())
{
out << "This is a line.\n";
out << "This is another line.\n";
out.close();
}
return 0;
}
文件读操作
// reading a text file
#include
#include
#include
int main () {
char buffer[256];
ifstream in("test.txt");
if (! in.is_open())
{ cout << "Error opening file"; exit (1); }
while (!in.eof() )
{
in.getline (buffer,100);
cout << buffer << endl;
}
return 0;
}
void open ( const char * filename,
ios_base::openmode mode = ios_base::in | ios_base::out );
void open(const wchar_t *_Filename,
ios_base::openmode mode= ios_base::in | ios_base::out,
int prot = ios_base::_Openprot);
参数:
filename 操作文件名
mode 打开文件的方式
prot 打开文件的属性 //基本很少用到,在查看资料时,发现有两种方式
**打开文件的方式(mode ): **
ios::app: //以追加的方式打开文件
ios::ate: //文件打开后定位到文件尾,ios:app就包含有此属性
ios::binary: //以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
ios::in: //文件以输入方式打开(文件数据输入到内存)
ios::out: //文件以输出方式打开(内存数据输出到文件)
ios::nocreate: //不建立文件,所以文件不存在时打开失败
ios::noreplace://不覆盖文件,所以打开文件时如果文件存在失败
ios::trunc: //如果文件存在,把文件长度设为0
打开文件的属性取值(prot ):
0:普通文件,打开访问
1:只读文件
2:隐含文件
4:系统文件
可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件
状态标志符:
除了eof()以外,还有一些验证流的状态的成员函数(所有都返回bool型返回值):
is_open():文件是否正常打开
bad():读写过程中是否出错(操作对象没有打开,写入的设备没有空间)
fail():读写过程中是否出错(操作对象没有打开,写入的设备没有空间,格式错误--比如读入类型不匹配)
eof():读文件到达文件末尾,返回true
good():以上任何一个返回true,这个就返回false
要想重置以上成员函数所检查的状态标志,你可以使用成员函数clear(),没有参数
获得和设置流指针
- 对于所有的输入输出流都有至少一个指针,指向下一个要操作的位置
ofstream put_point
ifstream get_point
fstream put_point和get_point
- 获取流指针位置
tellg(): 返回输入流指针的位置(返回类型long)
tellp(): 返回输出流指针的位置(返回类型long)
- 设置指针位置
seekg(long position): 设置输入流指针位置为第position个字符(文件首位置为开始位置)
seekp(long position): 设置输出流指针到指定位置
// position in output stream
#include // std::ofstream
int main () {
std::ofstream outfile;
outfile.open ("test.txt");
outfile.write ("This is an apple",16);
long pos = outfile.tellp();
outfile.seekp (pos-7);
outfile.write (" sam",4);
outfile.close();
return 0;
}
seekg ( off_type offset, seekdir direction );
seekp ( off_type offset, seekdir direction );
使用这个原型可以指定由参数direction决定的一个具体的指针开始计算的一个位移(offset)。它可以是:
ios::beg 从流开始位置计算的位移
ios::cur 从流指针当前位置开始计算的位移
ios::end 从流末尾处开始计算的位移
//假设test.txt中的内容是HelloWorld
ifstream fin("test.txt",ios::in);
cout << fin.tellg();//输出0,流置针指向文本中的第一个字符,类似于数组的下标0
char c;
fin >> c;
fin.tellg();//输出为1,因为上面把fin的第一个字符赋值给了c,同时指针就会向后 移动一个字节(注意是以一个字节为单位移动)指向第二个字符
fin.seekg(0,ios::end);//输出10,注意最后一个字符d的下标是9,而ios::end指向的是最后一个字符的下一个位置
fin.seekg(10,ios::beg);//和上面一样,也到达了尾后的位置
//我们发现利用这个可以算出文件的大小
int m,n;
m = fin.seekg(0,ios::beg);
n = fin.seekg(0,ios::end);
//那么n-m就是文件的所占的字节数
我们也可以从文件末尾出发,反向移动流指针,
fin.seekg(-10,ios::end);//回到了第一个字符
读取文件内容:
// print the content of a text file.
#include // std::cout
#include // std::ifstream
int main () {
std::ifstream ifs;
ifs.open ("test.txt", std::ifstream::in);
char c = ifs.get();
while (ifs.good()) {
std::cout << c;
c = ifs.get();
}
ifs.close();
return 0;
}
使用重载的’<<’ 或者 ‘>>’, 也可以使用成员函数来实现
#include
using namespace std;
int main ()
{
ifstream fr;
ofstream fw;
char word[200], line[200];
fw.open("write.txt");
fr.open("read.txt");
fr >> word; //读取文件,一个单词
fr.getline (line, 100); //读取一行内容
fw << "write file test" << endl;
fw.close();
fr.close();
return 0;
}
参考:
http://www.cplusplus.com/reference/fstream/ifstream/open/
https://www.cnblogs.com/journal-of-xjx/p/6679663.html
https://www.cnblogs.com/alihenaixiao/p/6429854.html