C++ IO输入输出

先看一下文件流与基本流彼此间的关系


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)......就先这么多吧!!!!


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值