标准 C++ 提供提供了一个增强的、面向对象的、具有国际化意识的 <fstream> 库。这个库包含一系列派生于标准 ios_base 和 ios 类的类模板。
输入文件流(ifstream)支持重载的 >> 操作符,同样,输出文件流(ofstream)支持重载的 << 操作符。结合了输入和输出的文件流被称为 fstream。下面的程序创建了一个 ifstream 对象:dict,并将该对象中的每一个单字显示到屏幕上:
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
string s;
cout<<"enter dictionary file: ";
cin>>s;
ifstream dict (s.c_str());
if (!dict)
exit(-1);
while (dict >> s)
cout << s <<'/n';
}
我们必须调用 string::c_str() 成员函数,因为 fstream 对象只接受常量字符串作为文件名。当你将文件名作为参数传递时,构造函数试图打开指定的文件。注意我们不必显式地检查 EOF,因为重载操作符 >> 会自动处理。此外,我们不用显式地关闭此文件,因为析构函数会为我们做这件事情。(比fstream的open()好)
但是open()函数是很有用的
以前的 <fstream.h> 库支持 ios::nocreate 和 ios::noreplace 标志。但新的 <fstream> 库已经取代了 <fstream.h> 并不再支持这两个标志。
注意,fstream只是打开文件,如果文件不存在的话并不会创建它,
如果你不显式指定打开模式,fstream 类将使用默认值。例如,ifstream 默认以读方式打开某个文件并将文件指针置为文件的开始处。为了向某个文件写入数据,你需要创建一个 ofstream 对象。<fstream> 定义了下列打开模式和文件属性:
ios::app // 从后面添加 ios::ate // 打开并找到文件尾 ios::binary // 二进制模式 I/O (与文本模式相对) ios::in // 只读打开 ios::out // 写打开 ios::trunc // 将文件截为 0 长度
你可以用位域操作符 OR 组合这些标志:
ofstream logfile("login.dat", ios::binary | ios::app);
fstream 类型对象同时支持读和写操作:
fstream logfile("database.dat", ios::in | ios::out);
文件具备一个逻辑指针,它指向该文件中的某个偏移位置。你可以通过调用seekp()成员函数,以字节为单位将这个指针定位到文件的任意位置。为了获取从文件开始处到当前偏移的字节数,调用seekp()即可。
ofstream fout("parts.txt"); fout.seekp(10); // 从0偏移开始前进 10 个字节 cout<<"new position: "<<fout.tellp(); // 显示 10
seekp()有一个重载版本seekp(位置,参数),
seekg(-5,ios::end);
在这个例子中,你将能够读到文件文本的最后4个字符,因为:
你先到达了末尾(ios::end)
你接着到达了末尾的前五个字符的位置(-5)
ios::beg // 文件开始位置
ios::cur // 当前位置,例如: ios::cur+5
ios::end // 文件尾
或许ios::end所“指”的根本已经超出了文件本身的范围,确切的说它是指向文件最后一个字符的下一个位置,有点类似STL中的各个容器的end迭代点是指向最后一个元素的下一位置。这样设计可能是便于在循环中实现遍历
看下面的实例:
void main()
{
fstream File("test.txt",ios::in | ios::out);
File << "Hi!"; //将“Hi!”写入文件
static char str[10]; //当使用static时,数组会自动被初始化
//即是被清空为零
File.seekg(ios::beg); // 回到文件首部
File >> str;
cout << str << endl;
File.close();
}
上面的实例是一个单词一个单词的读取的,如果文件中有这样的文本片断:
Hi! Do you know me?
使用File >> str,则只会将“Hi!”输出到str数组中。你应当已经注意到了,它实际上是将空格作为单词的分隔符进行读取的。
你也可以一行一行地进行读取,像这样:
char line[100]; //每个整行将会陆续被存储在这里
while(!OpenFile.eof())
{
OpenFile.getline(line,100); // 100是数组的大小
cout << line << endl;
}
那么如何检测文件是否打开正确呢
例1:最通常的作法Xfstream File(“cpp-home.txt”);if (!File)
{cout << “Error opening the file! Aborting…/n”;exit(1);
}例2:如果文件已经被创建,返回一个错误ofstream File("unexisting.txt", ios::nocreate);if(!File){cout << “Error opening the file! Aborting…/n”;exit(1);}例3:使用fail()函数ofstream File("filer.txt", ios::nocreate);if(File.fail()){cout << “Error opening the file! Aborting…/n”;exit(1);}fail()如果有任何输入/输出错误(不是在文件末尾)发生,它将返回非零值ifstream File; //也可以是一个ofstream这样,我们就拥有一个文件句柄,但我们仍然没有打开文件。如果你打算迟些打开它,那么可以用open()函数来实现,我已经在本教程中将它介绍了。但如果在你的程序的某处,你可能需要知道当前的句柄是否关联了一个已经打开的文件,那么你可以用is_open()来进行检测。如果文件没有打开,它将返回0 (false);如果文件已经打开,它将返回1 (true)。例如:ofstream File1;File1.open("file1.txt");cout << File1.is_open() << endl;上面的代码将会返回1ostream的一些成员函数
flush
Flushes the buffer.
put
Puts a character in a stream.
seekp
Resets position in output stream.
sentry
The nested class describes an object whose declaration structures the formatted output functions and the unformatted output functions.
tellp
Reports position in output stream.
write
Puts characters in a stream.istream的一些成员函数
gcount
Returns the number of characters read during the last unformatted input.
get
Reads one or more characters from the input stream.
getline
Reads a line from the input stream.
ignore
Causes a number of elements to be skipped from the current read position.
peek
Returns the next character to be read.
putback
Puts a specified character into the stream.
read
Reads a specified number of characters from the stream and stores them in an array.
readsome
Read from buffer only.
seekg
Moves the read position in a stream.
sentry
The nested class describes an object whose declaration structures the formatted input functions and the unformatted input functions.
sync
Synchronizes the input device associated with the stream with the stream's buffer.
tellg
Reports the current read position in the stream.
unget
Puts the most recently read character back into the stream.