C++程序设计【七】输入/输出流

第七章 输入/输出流

第一节 流类简介

  • C++中凡是数据从一个地方传输到另一个地方的操作都是的操作。因此,一般意义下的读操作在流数据抽象中被称为(从流中)“提取”,写操作被称为(向流中)“插入”。
  • 在C++中,输入输出的完成是通过
    在这里插入图片描述
  • 图7-1中的箭头代表派生关系。ios是抽象基类,提供输入/输出所需的公共操作,它派生出两个类istream和ostream。为了避免多重继承的二义性,从ios派生istream和ostream时,均使用了virtual关键字(虚继承)
    • istream类提供了流的大部分输入操作,对系统预定义的所有输入流重载提取运算符“>>”
    • ostream类对系统预定义的所有输出流重载插入运算符“<<”
    • 由istream和ostream又共同派生了iostream类。
  • C++的iostream类库提供了数百种I/O功能,iostream类库的接口部分包含在几个头文件中。常见的头文件有以下3个:
    • ① iostream
      • 头文件iostream包含操作所有输入/输出流所需的基本信息,因此大多数C++程序都应包含这个头文件。该文件含有4个标准流对象,提供了无格式化和格式化的I/O功能。
    • ② iomanip
      • 例如:setw(),setprecision(),setfill(),setbase()等。头文件iomanip包含格式化I/O的带参数流操纵符,可用于指定数据输入/输出的格式。
    • ③ fstream
      • 头文件fstream包含处理文件的有关信息,提供建立文件、读/写文件的各种操作接口。

第二节 标准流对象

  • C++在头文件iostream中为用户预定义了4个标准流对象,分别是:
    • cin(标准输入流)
      • cin与标准输入设备(键盘)相关联,用于读取数据,可以被重定向为从文件中读取数据
    • cout(标准输出流)
      • cout与标准输出设备(显示器、文件、内存等)相关联,用于输出数据,可以被重定向为向文件里写入数据
    • cerr(非缓冲错误输出流)
      • cerr与标准错误信息输出设备(显示器)相关联(非缓冲),用于输出出错信息,不能被重定向。
    • clog(缓冲错误输出流)
      • clog与标准错误信息输出设备相关联(缓冲),用于输出出错信息,不能被重定向。
  • 在实际中,cin常用于从键盘输入数据,是流类istream的对象。cout常用于向屏幕输出数据,是流类ostream的对象。

第三节 控制I/O格式

一、流操纵符(#include <iomanip>)

C++进行I/O格式控制的方式一般有使用流操纵符、设置标志字和调用成员函数。

流操纵符作用输入/输出
endl换行符,输出一个新行符,并清空流O
ends输出字符串结束,并清空流O
flush清空流缓冲区O
dec*(默认)以十进制形式输入或输出整数I/O
hex以十六进制形式输入或输出整数I/O
oct以八进制形式输入或输出整数I/O
ws提取空白字符O
fixed以普通小数形式输出浮点数
scientific以科学计数法形式输出浮点数
left左对齐,即在宽度不足时将填充字符添加到右边
right *右对齐,即在宽度不足时将填充字符添加到左边
setbase(int b)设置输出整数时的进制,b为8、10或16
setw(int w)指定输出宽度为w个字符,或输入字符串时读入w个字符。一次有效
setfill(int c)在指定输出宽度的情况下,输出的宽度不足时用ASCII码为c的字符填充(默认情况是用空格填充)
setprecision(int n)设置输出浮点数的精度为n。在使用非fixed且非scientific方式输出的情况下,n即为有效数字最多的位数。如果有效数字位数超过n,则小数部分四舍五入,或自动变为科学计数法输出并保留一共n位有效数字;在使用fixed方式scientific方式输出的情况下,n是小数点后面应保留的位数
setiosflags(fmtfalgs f)通用操纵符。将格式标志f所对应的格式标志位置为1
resetiosflags(fmtfalgs f)通用操纵符。将格式标志f所对应的格式标志位置为0(清除)
boolapha把true和false输出为字符串
noboolalpha *把true和false分别输出为1和0
showbase输出表示数值进制的前缀
noshowbase *不输出表示数值进制的前缀
showpoint总是输出小数点
noshowpoint *只有当小数部分存在时才显示小数点
showpos在非负数值中显示+
noshowpos *在非负数值中不显示+
skipws *输入时跳过空白字符
noskipws输入时不跳过空白字符
uppercase十六进制数中使用’A’~’E’。若输出前缀,则前缀输出“0x”,科学计数法中输出’E’
no uppercase *十六进制数中使用’a’~’e’。若输出前缀,则前缀输出“0x”,科学计数法中输出’e’
internal数值的符号(正负号)在指定宽度内左对齐,数值右对齐,中间由填充字符填充
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
	int n=65535,m=20;
	//(1)分别输出一个整数的十进制,十六进制和八进制表示
	cout<<"(1)(十进制)"<<n<<"=(十六进制)"<<hex<<n<<"=(八进制)"<<oct<<n<<endl;
	//(2)使用setbase分别输出一个十进制、十六进制和八进制表示
	cout<<"(2)(十进制)"<<m<<"=(十六进制)"<<setbase(10)<<m<<"=(八进制)"<<setbase(8)<<m<<endl;
	//(3)使用showbase和setbase分别输出一个十进制、十六进制和八进制表示
	cout<<"(3)"<<showbase;	//输出表示数值进制的前缀
	cout<<"(十进制)"<<m<<"=(十六进制)"<<setbase(10)<<m<<"=(八进制)"<<setbase(8)<<m<<endl;

	return 0;
}

在这里插入图片描述

二、标志字

标志常量名含义输入/输出
ios::skipws0X0001跳过输入中的空白I
ios::left0X0002按输出域左对齐,用填充字符填充右边O
ios::right *0X0004按输出域右对齐,用填充字符填充左边O
ios::internal0X0008在符号位或基数指示符后填入字符O
ios::dec *0X0010转换为十进制基数形式I/O
ios::oct0X0020转换为八进制基数形式I/O
ios::hex0X0040转换为十六进制基数形式I/O
ios::showbase0X0080在输出中显示基数指示符O
ios::showpoint0X0100在输出浮点数时必须带小数点和尾部的0O
ios::uppercase0X0200以大写字母表示十六进制数,科学计数法使用大写字母EO
ios::showpos0X0400正数前加“+”号O
ios::scientific0X0800科学记数法显示浮点数O
ios::fixed0X1000定点形式表示浮点数O
ios::unitbuf0X2000插入操作后立即刷新流O
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
	double x=12.34;
	/** setiosflags(int n)	——设置输出浮点数的精度为n。
		ios::scientific		——科学计数法显示浮点数。
		ios::showpos		——整数前加“+”号。
	*/
	cout<<"(1)"<<setiosflags(ios::scientific |ios::showpos)<<x<<endl;	//(1)+1.234000e+001
	
	//ios::fixed			——定点形式表示浮点数
	cout<<"(2)"<<setiosflags(ios::fixed)<<x<<endl;				//(2)+0x1.8ae148p+3

	//resetiosflags(fmtflags f)——通用操纵符。将格式标志f所对应的格式标志位置为0(清除)
	cout<<"(3)"<<resetiosflags(ios::fixed)
		<<setiosflags(ios::scientific |ios::showpos)<<x<<endl;	//(3)+1.234000e+001

	//清除要输出正号的标志
	cout<<"(4)"<<resetiosflags(ios::showpos)<<x<<endl;			//(4)1.234000e+001

	return 0;
}

第四节 调用cout的成员函数

成员函数作用相同的流操纵符
precision(int np)setprecision(np)
width(int nw)setw(nw)
fill(char cFill)setfill(cFill)
setf(long iFlags)setiosflags(iFlags)
unsetf(long iFlags)resetiosflags(iFIags)
#include <iostream>
using namespace std;
int main()
{
	double values[]={1.23,20.23456,300.4567,4000.45678,50000.1234567};
	//设置填充字符为星号*
	cout.fill('*');

	for(int i=0;i<sizeof(values) / sizeof(double);i++)
	{
		cout<<"values["<<i<<"]=(";
		cout.width(10);	//设置输出宽度
		cout<<values[i]<<")"<<endl;
	};

	//设置填充字符为空格
	cout.fill(' ');
	for(int i=0;i<sizeof(values) / sizeof(double);i++)
	{
		cout<<"values["<<i<<"]=(";
		cout.width(10);			//设置输出宽度
		cout.precision(i+3);	//设置保留有效数字
		cout<<values[i]<<")"<<endl;
	};

	return 0;
}

在这里插入图片描述

#include <iostream>
using namespace std;

int main()
{
	char c = 'a';
	char str[80]="0123456789abcdefghijklmn";

	int x=65;

	cout<<"cout.put('a'):";
	cout.put(c);		//cout.put('a'):a

	cout<<"\n cout.put(c+25):";
	cout.put(c+25);		//cout.put('a'):z

	cout<<"\n cout.write(str,20):";
	//将str的前20个字节写入到输出流中
	cout.write(str,20);	//cout.write(str,20):0123456789abcdefghij

	return 0;
}

在这里插入图片描述

第五节 调用cin的成员函数

istream类提供了一些公有成员函数,它们可以以不同的方式提取输入流中的数据。

一、get()函数

/**	在Windows环境下,
	当进行键盘输入时,在“单独的一行”按〈Ctrl+Z〉组合键后再按〈Enter〉键
	就代表文件输入结束。	*/
#include <iostream>
using namespace std;
int main()
{
	int n=0;
	char ch;
	//当文件没有结束时继续进行循环
	while( (ch=cin.get()) != EOF )
	{
		cout.put(ch);
		n++;
	}
	cout<<"输入字符共计:"<<n<<endl;

	return 0;
}

在这里插入图片描述

二、getline()函数

getline( )成员函数的原型如下: 从输入流中读取一行字符
istream & getline(char * buf, int bufSize);
  其功能是从输入流中的当前字符开始读取bufSize-1个字符到缓冲区buf,或读到’\n’为止(哪个条件先满足即按哪个执行)。函数会在buf中读入数据的结尾自动添加串结束标记’\0’。
istream & getline(char * buf, int bufSize, char delim);
  其功能是从输入流中的当前字符开始读取bufSize-1个字符到缓冲区buf,或读到字符delim为止(哪个条件先满足即按哪个执行)。函数会在buf中读入数据的结尾自动添加’\0’。

  • 两者的区别在于,前者是读到’\n’。为止,后者是读到指定字符delim为止。
  • 字符’\n’或delim都不会被存入buf中,但会从输入流中取走。
  • 函数getline( )的返回值是函数所作用的对象的引用。如果输入流中’\n’或delim之前的字符个数达到或超过bufSize,则会导致读入操作出错,其结果是:虽然本次读入已经完成,但是之后的读入都会失败。
#include <iostream>
using namespace std;
int main()
{
	char buf[10];
	int i=0;

	//若输入流的一行超过9字符,则回出错
	while(cin.getline(buf,10))
		cout<<++i<<":"<<buf<<endl;

	cout<<"last:"<<buf<<endl;

	return 0;
}

在这里插入图片描述

三、eof()函数

  • eof( )成员函数的原型如下:  bool eof();
  • eof( )函数用于判断输入流是否已经结束。返回值为true表示输入结束。
  • 在应用程序中可以用eof()函数测试是否到达文件尾,当文件操作结束遇到文件尾时,函数返回1;否则返回0。

四、ignore()函数

ignore()成员函数的原型如下:
istream & ignore(int n=1, int delim=EOF);

  • 此函数的作用是跳过输入流中的n个字符,或跳过delim及其之前的所有字符(哪个条件先满足就按哪个执行)。
  • 两个参数都有默认值。因此cin.ignore( )等效于cin.ignore(1,EOF),即跳过一个字符。该函数常用于跳过输入中的无用部分,以便提取有用的部分。
#include<iostream>
using namespace std;
int main()
{
	char str[30];
	while(!cin.eof())
	{
		cin.ignore(10,':');

		if(!cin.eof())
		{
			cin>>str;
			cout<<str<<endl;
		}
	}
	return 0;
};

在这里插入图片描述

五、peek()函数

  • peek()成员函数的原型如下:  int peek( );
  • 函数peek()返回输入流中的当前字符,但是并不将该字符从输入流中取走——相当于只是“看了一眼”将要读入的下一个字符,因此叫“窥视”。
  • cin.peek( )不会跳过输入流中的空格和回车符。在输入流已经结束的情况下,cin.peek( )返回EOF。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值