C++STL输入输出流

1.标准输入的不足

<span style="font-family:SimSun;font-size:14px;">#include<iostream>
using namespace std;
int main()
{
     int i;
     char str[20];
     cout<<"请输入一个整型数及一个字符串:";
     cin>>i>>str;
     cout<<"i="<<i<<endl;
     cout<<"str="<<str<<endl;
     return 0;
}</span><span style="font-size: 18px;">
</span>

若在命令行上输入1 how are you ? ,按Enter键后执行结果为:

i=1  str=how

原因在于命令行中各参数默认是以空格为界定符的,可以用get系列函数解决这个问题。

2.get系列函数

 常用的有3个函数。

(1)int get() ;返回输入流一个字符的ASCII值。

(2)istream& get(unsigned char* pszBuf, int nBufLen, char   delim=’\n’);

pszBuf:指向字符缓冲区的指针,用于保存结果

nBufLen:缓冲区长度

delim:结束字符,根据结束字符判断何时停止读入操作

(3)istream& getline(unsigned char* pszBuf, int nBufLen, char delim=’\n’);

get ,getline函数简单示例

<span style="font-size:14px;">#include<iostream>
using namespace std;
int main()
{
   char str[60];
   cout<<"请输入一个字符串:";
   int n=cin.get();
   cin.getline(str,60);
   cout<<n<<endl;
   cout<<str<<endl;
   return 0;
}
</span>
若输入How are you?

输出:

72

ow are you?

H的ASCII码为72.   getline()函数第三个参数默认结束标志符是“\n”.

3. 处理流错误

获取状态信息的函数如下:

int rdstate();无参数,返回值既是状态信息特征值。

使用下面函数来检测相应输入/输出状态:

bool good();若返回值true,一切正常,没有错误发生。

bool eof();  若返回值true,表明已到达流的末尾。

bool fail();若返回值true,表明I/O操作失败,主要原因是非法数据(例如读取数字时遇到字母)。但流可以继续使用。

bool bad();  发生了(或许是物理上的)致命性错误,流将不能继续使用。


1.判断是否输入整形数。


#include <iostream>
using namespace std;
int main() { 
	int a;
	cout << "请输入一个数据: ";
	cin>>a;
	cout<<"状态值为: " <<cin.rdstate()<<endl;
	if(cin.good())
	{
		cout<<"输入数据的类型正确,无错误!"<<endl;
	}
	if(cin.fail())
	{
		cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
	}
	return 0;
}

2.确保输入一个整形数给变量a

#include <iostream>
using namespace std;
int main() { 
	int a;
	while(1)
	{
	cin>>a;			//赋值给整形数a
	if(cin.fail())	//如果输入数据非法,则:
	{
		cout<<"输入有错!请重新输入"<<endl;
		cin.clear();//清空状态标识位
		cin.get();	//清空流缓冲区
	}
	else			//如果输入数据合法,则:
	{
		cout<<a<< endl;    //直接在屏幕上输出数据
		break;		//跳出while循环
	}
      }
return 0;
}

4.文件输入输出流

C++对文件的读写使用的是ifstream、ofstream和fstream流类,同样是依照“打开-->读写-->关闭”原语进行操作。文件读写所用到的很多常数都在基类ios中被定义出来。ifstream类只用于读取文件数据,ofstream类只用于写入数据到文件,fstream则可用于读取和写入文件的数据。

ios::in      以读取方式打开文件


ios::out    以写入方式打开文件


ios::app   每次写入数据时,先将文件指针移到文件尾,以追加数据到尾部


ios::ate    仅初始时将文件指针移到文件尾,仍可在任意位置写入数据


ios::trunc 写入数据前,先删除文件原有内容(清空文件),当文件不存在时会创建文件


ios::binary以二进制方式打开文件,不作任何字符转换.

(1)读文本文件并显示在屏幕上

#include <fstream>
#include <iostream>
using namespace std;
int main(){
	char szBuf[80];
	ifstream in("a.txt");//通过构造函数创建文件读入流
	if(!in) return 0;		//若文件不存在,返回
	while(in.getline(szBuf, 80)) //通过getline函数按行读取内容
	{
	cout << szBuf << endl;	//将读入缓冲区内容输出到屏幕上,判断是否正确
	}
	
	in.close();
	return 0;
}



(2)写文本文件:把学生成绩信息保存至文件

<span style="font-size:14px;">#include <fstream>
#include <iostream>
using namespace std;
struct STUDENT	//学生成绩结构体
{
	char strName[20];	//姓名
	int  nGrade;		//成绩
};
int main() {
	ofstream out;
	out.open("d:\\a.txt");	//打开或创建a.txt文本文件
	STUDENT st1 ={"张三", 90};//用结构体产生两名学生的成绩信息
	STUDENT st2 ={"李四", 80};
	out << st1.strName << "\t" << st1.nGrade << endl;//把成绩信息存到文本文件
	out << st2.strName << "\t" << st2.nGrade << endl;
	out.close();
	return 0;
} </span><span style="font-size: 24px;">
</span>

可以看出,通过“<<”完成写文本文件是一个较好的方法,这是因为“<<”操作符可把不同类型的数据直接输出。结构体中strName是

字符串,nGrade是整形数,但均可直接输出到文件上即可。此外strName与nGrade之间采用“\t”输出是为了数据对齐,

而“endl”保证输出“\n”回车符,保证了文本文件的换行,是必须的。

(3)读写二进制文件

主要是通过read()、write()函数完成读写二进制文件功能的,原型如下所示

ostream& write(const char *, int nSize)

istream& read(char *, int nSize)

第1个参数表明读写缓冲区的头指针,第二个参数表明读写缓冲区的大小

(4)写二进制文件:把学生成绩信息保存至文件中

<span style="font-size:14px;">#include <fstream>
#include <iostream>
using namespace std;
struct STUDENT	//学生成绩结构体
{
	char strName[20];	//姓名
	int  nGrade;		//成绩
};
int main() {
	ofstream out;
	out.open("d:\\a.txt");	//打开或创建a.txt文本文件
	STUDENT st1 ={"张三", 90};//用结构体产生两名学生的成绩信息
	STUDENT st2 ={"李四", 80};
	out.write((const char *)&st1, sizeof(STUDENT));	//把成绩信息存到二进制 文件
	out.write((const char *)&st2, sizeof(STUDENT));
	out.close();
	return 0;
} 
</span>


(5)读二进制文件,并把结果显示在屏幕上。

<span style="font-size:14px;">#include <fstream>
#include <iostream>
using namespace std;
struct STUDENT
{
	char strName[20];	//姓名
	int  nGrade;		//成绩
};
int main() {
	ifstream in;
	in.open("d:\\a.txt");
	if(!in) return 0;
	STUDENT st1;
	STUDENT st2;
	in.read((char *)&st1, sizeof(STUDENT));
	in.read((char *)&st2, sizeof(STUDENT));
	cout << st1.strName << "\t" << st1.nGrade << endl;
	cout << st2.strName << "\t" << st2.nGrade << endl;
	in.close();
	return 0;
} </span><span style="font-size: 24px;">
</span>

(3) 输入输出流缓冲

C++标准库封装了一个缓冲区类streambuf,以供输入输出流对象使用。每个标准C++输入输出流对象都包含一个指向streambuf的指针,

用户可以通过调用rdbuf()成员函数获得该指针,从而直接访问底层streambuf对象,可以直接对底层缓冲区进行数据读写,从而跳过上层

的格式化输入输出操作。但由于类似的功能均可由上层缓冲区类实现,所以就不再加以论述了。streambuf最精彩的部分在于它重载了

operator <<及operator >>。对operator <<来说,它以streambuf指针为参数,实现把streambuf对象中的所有字符输出到输出流出中;对

operator >>来说可把输入流对象中的所有字符输入到streambuf对象中。


(6)打开一个文件并把文件中的内容送到标准输出中。

<span style="font-size:14px;">#include <fstream>
#include <iostream>
using namespace std;
int main() {
    ifstream fin("d:\\my.txt");
	if(fin !=NULL)			//判断文件是否存在
	{
		cout<<fin.rdbuf();  //把文件所有内容输出到屏幕上
	}
	fin.close();	
}</span><span style="font-size: 24px;">
</span>

(4)定位输入输出流

流的位置标识有3个:

ios::beg流的开始位置

ios::cur流的当前位置

ios::end流的结束位置

定位函数主要有两个:

·istream& seekg(long relativepos, ios::seek_dir dir)

针对输入流。第1个参数是要移动的字符数目,可正可负;第2个参数是移动方向,是ios::begin, ios::cur, ios::end中的一

个值。含义是:字符指针相对于移动方向移动了向前或向后移动了多少个字符。

ostream& seekp(long relativepos, ios::seek_dir dir)

针对输出流。参数含义同seekg.


下面示例先写文件,然后再把文件内容读出显示在屏幕上。

<span style="font-size:32px;">  </span><span style="font-size:24px;">#include <fstream>
#include <iostream>
using namespace std;
int main() {
	fstream	in_out;
	in_out.open("d:\\my.txt",ios::in|ios::out|ios::trunc);
	in_out.write("Hello", 5);
	in_out.seekg(0, ios::beg);  //读指针移到文件头
	cout << in_out.rdbuf();
	in_out.close();
	return 0;
}</span><span style="font-size:32px;">
</span>

5.字符串输入输出流

标准库定义了三种类型的字符串流。

istringstream输入流,提供读string功能

ostringstream输出流,提供写string功能

stringstream输入输出流,读写string功能


(1)反解字符串给各变量赋值


#include <iostream>
#include <sstream>
using namespace std;
int main()
{
	int n;
	float f;
	string strHello;
	string strText = "1 3.14 hello";
	istringstream s(strText);
	s >> n;
	s >> f;
	s >> strHello;
	cout << "n= " << n << endl;
	cout << "f= " << f << endl;
	cout << "strHello= " << strHello << endl;
	return 0;
} 

(2)合并不同类型的数据到字符串

  #include <iostream>
#include <sstream>
using namespace std;
int main()
{
	cout << "type an int,a float and a string: ";
	int i;
	float f;
	string stuff;
	cin >> i >> f;
	getline(cin, stuff);
	ostringstream	os;
	os << "integer= " << i << endl;
	os << "float= " << f << endl;
	os << "string= " << stuff << endl;
	string result = os.str();
	cout << result << endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值