先看一下文件流与基本流彼此间的关系
cin(从设备[键盘]读数据),cout(向设备[屏幕]输出数据)俩个对象分别为istream和ostream定义的全局对象(为什么!因为是标准设备)。
(1) ifstream,ostream,fstream 包含头文件<fstream.h>
而ifstream等非标准设备就得自行定义对象,毕竟目标对象(要打开的文件)不可知是吧!废话不多说...先上ifstream函数原型:
ifstream(const char *, int mode=ios::in, int openprot= filebuf::openprot);
mode(文件打开方式):
1.app 追加文件尾,ate 和app效果是一样的将光标定位置文件尾。但使用运算符“<<”时ate会覆盖原文件内容
2.binary 以二进制形式打开文件,当然缺省的情况下以文件形式打开。
3.in 以输入流打开(可读不可写),out 以输出流打开(可写不可读)。
4.trunc 打开文件的同时清空文件内容。
openprot(文件属性): 普通文件(0),只读文件(1),隐藏文件(2),系统文件(4)
对于ofstream一样只不过mode默认只能为为out,ifstream默认只能为为in。
但是使用fstream虽然可以同时进行文件的读写,所以初始化时必然要指定mode和openprot,不然不能保证能很有效的进行文件流输入输出。
上例子(将两个文件的内容拼接,放入第三文件中):
#include<sstream>
#include<fstream>
using namespace std;
void main()
{
stringstream addString;
int strLen;
//读取One文件,并将内容放入addString
fstream myFile("One.txt", ios::ate|ios::in);
if (!myFile) //判断文件是否打开成功
exit(-1);
strLen = myFile.tellg();
myFile.seekg(0); //读指针定义至文件头
char *one = new char[strLen+1];
one[strLen] = '\0'; //保证字符串以'\0'结尾,避免出现乱码
myFile.read(one, strLen); //按字长读取文件并放入one字符串指针中
addString<<one; //
myFile.close();
//读取Two文件,并将内容放入addString
myFile.open("Two.txt", ios::ate|ios::in);
if (!myFile)
exit(-1);
strLen = myFile.tellg();
myFile.seekg(0);
char *two = new char[strLen+1];
two[strLen]='\0';
myFile.read(two, strLen);
addString<<two;
myFile.close(); //关闭文件
//将addstring内容写入到Add文件中
myFile.open("Add.txt", ios::out|ios::trunc);
myFile<<addString.str();
}
下面说说它们的内部函数:
1.随机存储
用于读文件的随机存储
tellg() 返回读取的位置
seekg( pos ) 从当前位置移动pos个位子(绝对移送)
seekg( offset, rpos ) 以rpos位置开始移动offset个位置(相对移动)
用于写文件的随机存储
tellp() 返回写入的位置
seekp( pos ) 从当前位置移动pos个位子(绝对移送)
seekp( offset, rpos ) 以rpos位置开始移动offset个位置(相对移动)
2.行读取操作
getline(char *str, int max_size, char='\n')
第一个参数是 字符数组,用于存放整行文本,第二参数 为读取的最大字符数,第三为 截止字符
3.说到这就随便了解一下输入输出的状态标志(包含在io_state对象中):
goodbit 无错误
eofbit 已达文件尾
failbit 非致命输入\输出错误,可挽回
badbit 致命错误,不可挽回
如果想要获得该信息可以通过两种方式:1.调用rdstate() 2.调用对应的函数如bad(),eof()。
要注意的是当错误发生时,流状态即被标记为错误,要继续对文件进行操作必须清除错误状态,该过程可以通过clear(int state)函数进行清除
【state 为当前要改变为状态的标记,例:ios::goodbit(默认)】
值得注意的是在open成功后不会对 fstream中状态进行操作,而open失败的话会设置_MyState为failbit,并且在close操作时如果本身是空文件,
也会设置state为failbit,这样造成一次失败之后的其他很多操作都是失败的,因为很多fstream操作会先判断state;而clear函数是将fstream状态重置为goodbit
再上例子(读取noLineNum.txt文件将文件中的每行文本加行号并保存至LineNum.txt中)
#include <iostream>
#include<sstream>
#include<fstream>
using namespace std;
void main()
{
stringstream addString;
int strLen;
//读取文件,并将内容放入addString并添加行号
fstream myFile("noLineNum.txt", ios::ate|ios::in);
if (myFile.rdstate() == ios::failbit) //文件open失败的话会设置State为failbit
exit(-1);
strLen = myFile.tellg(); //获得读指针所在的绝对位置
myFile.seekg(0); //将读指针置文件头
char *line;
line = (char *) malloc(0);
for(int i = 1; myFile.eof()!=ios::eofbit; i++)
{
myFile.getline(line,strLen);
addString<<i<<':'<<line<<'\n';
}
myFile.clear(ios::goodbit);//在对一个文件操作结束时,应调用clear,要是没这句话你会发现字符串怎么也写不进LineNum.txt
myFile.close();
//将添加了行号的文本保存入LineNum.txt中
myFile.open("LineNum.txt", ios::out|ios::trunc);
myFile<<addString.str();
}
(2)istrstream,ostrstream,strstream,包含头文件<strstream.h>
这三个类主要用于执行C风格的串流输入输出(即以字符串数组作为输入输出设备)
只拿一个说明一下其他一样的:
先说明一下串流同样不是标准设备,不会有预先定义的全局对象,需要调用构造函数创建对象:
istrstream(const char *str, int size)//当size为0时类对象直接指向str指向的内存空间,并以\0结尾的字符串
(3)ostringstream,istringstream,stringstream 包含头文件<sstream.h>
这三个类主要用于执行C++风格的串流输入输出(即以string作为输入输出设备):
istringstream(string str) //将str输出至其他流等
ostringstream(string str) //向str插入其他流等
总的来说基本掌握了就OK了,毕竟我还是不经常用到(以上内容部分学习自www.cndev.lab.com)......就先这么多吧!!!!