c++复习之输入输出流


c++中输入与输出都是通过流来完成。

知识点

流类

C++ 的开发者认为数据输入和输出的过程也是数据传输的过程,数据像水一样从一个地方流动到另一个地方,所以 C++ 中将此过程称为“流”,将与数据输入/输出相关的类称为流类

常用的流类及关系

如下图所示:
在这里插入图片描述

常用输入输出流列表

类名说明包含文件
抽象流基类ios流基类ios
输入流基类istream通用输入流基类和其他输入流基类。cin是该类的对象;常用于接收从键盘输入的数据istream
ifstream文件输入流类,用于从文件读取数据fstream
输出流类ostream通用输出流基类和其他输出流基类。cout是该类的对象;常用于将数据输出到屏幕上;ostream
ofstream文件输出流类,用于向文件写入数据fstream
输入输出流类 iostream通用输入输出流基类和其他输入输出流基类;继承自 istream 和 ostream 类,因为该类的功能兼两者于一身,既能用于输入,也能用于输出;iostream
fstream文件输入输出流类;兼 ifstream 和 ofstream 类功能于一身,既能读取文件中的数据,又能向文件中写入数据。fstream

避免多重继承二义性问题,从ios派生istream和ostream时,均使用了virtual(虚继承)。

iostream类库头文件

  1. iostream:包含所有输入输出 流所需的基本信息。包含4个标准流对象,详见下面“标准流对象”,提供无格式和有格式化的i/o功能。
  2. iomanip:包含格式化i/o的带参数流操纵符,指定数据格式
  3. fstream;处理文件的有关信息,提供建立文件、读写文件的各种操作接口。

iostream定义的4种标准流对象

为用户提供常用外设与内存之间通信的通道,对数据进行解释和传输,提供必要的数据缓冲等。
4个标准的流对象

cin:

用于从键盘输入数据

cout:

用于向屏幕输出数据1,可以重定向输出到文件,使用freopen函数重定向
FILE *freopen(const char *path,const char *mode,FILE *stream);//mode是指定模式,w(写),t(读)path是输出文件名,steam就是输出流或输入流,如stdin或stdout,失败关闭原来的stream返回NULL,成功返回文件名

实例
#include <fstream>
#include<iomanip>
#include<iostream>
using namespace std;
int main()
{
    int a;
    fstream fs("abc.txt", ios::in | ios::out | ios::trunc);
    fs << 1 << " " << 2 << " " << 3 << endl;//重定向到文件流,插入1 2 3
    fs.seekp(0, ios::beg);//设置输出流指针位置
    int x, y, z;
    fs >> x >> y >> z;//从文件中提取出字符
    cout << x << y << z << endl;
}

cerr(非缓冲错误输出流)

直接向显示器输出信息,不能重定向
cerr 也是与流插入运算符 << 结合使用的,

实例
#include <iostream>
using namespace std;
int main()
{
    char str[] = "Unable to read....";
    cerr << "Error message : " << str << endl;//Error message : Unable to read....
    return 0;
}
clog(缓冲错误输出流,也叫日志输出流)

先存储到缓冲区,缓冲区满或刷新时才输出到屏幕。
clog 也是与流插入运算符 << 结合使用的

总结
对象含义对应设备对应的类c语言中相应的标准文件
cout标准输出流屏幕ostream_withassignstdout
cerr标准错误流屏幕ostream_withassignstderr
clog标准错误流屏幕ostream_withassignstderr
cin标准输入流键盘istream_withassignstdin

在iostream头文件中定义以上4个流对象用以下的形式(以cout为例):
ostream cout ( stdout);
在定义cout为ostream流类对象时,把标准输出设备stdout作为参数,这样它就与标准输出设备(显示器)联系起来,如果有
cout <<3;

ios类定义的错误状态字及函数

流的状态可以通过检测ios_base类中的位来判断。

错误状态字:

goodbit

0x00,流状态正常位
如果流中的eofbit、failbit 和 badbit位都没有被设置,那么goodbit位将被设置
即如果函数eof, fail 和 bad都返回false值,则成员函数good返回true值。I/O操作只在“好的”流中才能进行。

eofbit,

0x01,文件结束符位
可以调用函数 cin.eof()来判断是否到达文件末尾
在cin中遇到问价末尾时返回true,否则返回false。

failbit

0x02,操作失败,数据未丢失,可以恢复
如程序要求输入整数,但是在输入流中有非整数的字符的情况。在遇到这种错误时,这些字符不会丢失。
成员函数fail将报告流操作失败了,通常这种错误是可以恢复的。

badbit

0x04,非法操作,数据丢失
成员函数bad将报告流操作是否失败了。一般情况下,这种严重的错误是不能修复的。

有关函数

  1. int eof()const
    功能:测试是否到文件尾,到了返加1,否则返回0.crtl+z表示输入流结束。
  2. int fail()coust
    功能:流操作是否失败,失败返加1,否则返回0
  3. int good()const
    int operator void *();
    功能:两个函数功能一样,如果eofbit,failbit和badbit都没有被置位,返回1,否则返回0.
  4. int bad()const
    int operator void!()
    功能:同上,只要三个位中有一个被置位,返回1,否则返回0
  5. int rdstate()const;
    功能:返回流的当前状态,返回流中的错误状态
    如,通过调用cout.rdstate返回流的状态,然后通过switch语句检查eofbit、badbit、failbit 和 goodbit来检查这些状态。
    检测流状态的首选方法是使用成员函数eof, fial, bad 和 good, 使用这些函数不要求了解具体的状态位
  6. void clear(int nStata=0);
    功能:恢复状态字,即将流状态恢复为正常。
    clear函数的默认参数是goodbit所以语句
    cin.clear()
    清空了cin, 并且为该流设置goodbit位。
    语句cin.clear(ios::failbit)则为流设置failbit位

实例

#include<iostream>
#include<iomanip>

using namespace std;
int main()
{
    int integerValue;
    cout << "Before a bad input operation:"
         << "\ncin.rdstate():" << cin.rdstate()// cin.rdstate():0
         << "\ncin.eof():" << cin.eof()// cin.eof():0
         << "\ncin.fail():" << cin.fail()// cin.fail():0
         << "\ncin.bad():" << cin.bad()// cin.bad():0
         << "\ncin.good():" << cin.good()// cin.good():1
         << "\n\nExpects an integer, but enter a character:";

    cin >> integerValue;
    cout << endl;

    cout << "After a bad input operation:"
         << "\ncin.rdstate():" << cin.rdstate()// cin.rdstate():4
         << "\ncin.eof():" << cin.eof()// cin.eof():0
         << "\ncin.fail():" << cin.fail()// cin.fail():1
         << "\ncin.bad():" << cin.bad()// cin.bad():0
         << "\ncin.good():" << cin.good() << endl << endl;// cin.good():0
    cin.clear();
    cout << "After cin.clear()" << "\ncin.fail():" << cin.fail()// After cin.clear()
         << "\ncin.good():" << cin.good() << endl;// cin.fail():0
                                                  // cin.good():1
    return 0;
}

i/o格式控制,即cin和cout 输入或输出格式控制

一般有使用流操纵符、设置标志字和调用成员函数。

iomanip中定义的流操纵符(格式控制符,不带参数)

endl:输出一个新行符,并清空流
ends:输出字符串结束,并清空流
flush:清空流缓冲区
dec* :以十进制形式输入或输出整数,*不是操纵符一部分,表示是默认设置。
hex:以十六进制形式输入或输出整数
oct:以八进制形式输入或输出整数
ws:提取空白字符

iomanip中定义的流操纵符(带参),考点

setbase(int b):设置输出整数时的进制
setw(int w):指定输出宽度为w个字符,或输入字符串时读入w个字符。一次有效,有小数点等要算个数
setfill()配合setw使用,设置其他字符填充
==setprecision(int n):==浮点值可以四舍五入到若干位有效数或精度,这是出现在小数点前后的总位数。控制显示浮点数值的有效数的数量。precision:英文 精度 的意思。小数点不算个数。要充分理解有效个数,如0.0321,保留两位有效位数,应该是:0.032
noboolapha*:把true和false 分别输出为1或0
showbase:输出表示数值进制的前缀,十六进制是0x
noshowpoint*:只有当小数部分存在时才显示的小数点

实例

注意与调用cout或cin成员函数时的不同。调用操纵符是cout<<+直接跟操作纵函数

#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    int n = 64;
    double d = 123.45;
    double d2 = 0.0183;
    //精度控制会影响下面的输出
    cout << setprecision(4) << d << endl; //控制有效数字的位数  123.5
    cout << setprecision(2) << d2 << endl;//四舍五入,而不是简单的截断  0.018
    cout << d << endl;//1.2e+02
    cout << setiosflags(ios::fixed);      //控制小数点后面的位数
    cout << setprecision(4) << d << endl; //同样是四舍五入  123.4500
    cout << setprecision(2) << d2 << endl;//0.02
//进制控制
    cout << "dec: " << n << endl;//dec: 64
    cout << "oct: " << oct << n << endl;//oct: 100
    cout << "hex: " << hex << n << endl;//hex: 40
    cout << n << endl;//40
    cout << setiosflags(ios::showbase);//显示对应进制前面的符号
    cout << "dec: " << dec << n << endl;
    cout << "oct: " << oct << n << endl;//oct: 0100
    cout << "hex: " << hex << n << endl;//hex: 0x40
    cout << setbase(8) << n << endl;   //进制输出 0100
    cout << setbase(10) << n << endl;//64
    cout << setbase(16) << n << endl;//0x40
}

setiosflags()函数可设置的标志字

头文件iostream中的setiosflags()函数用以设置指定的显示格式的标志字,函数的参数为流的格式标志位。如下图所示:
在这里插入图片描述
在这里插入图片描述

调用cout成员函数,考点

控制输出格式,作用和对应的流操纵符相同,如下图:因为是调用成员函数的形式,所以不需要 iomanip头文件
在这里插入图片描述

C++ cout 输出流对象常用成员方法:
成员方法名功能
put()输出单个字符。
write()输出指定的字符串。
tellp()用于获取当前输出流指针的位置。
seekp()设置输出流指针的位置。
flush()刷新输出流缓冲区。
operator<<重载 << 运算符,使其用于输出其后指定类型的数据。
实例
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    cout << setiosflags(ios::left | ios::showpoint); // 设左对齐,以一般实数方式显示
    cout.precision(5);       // 设置除小数点外有五位有效数字
    cout << 123.456789 << endl;//123.46
    cout.width(10);          // 设置显示域宽10
    cout.fill('*');          // 在显示区域空白处用*填充
    cout << resetiosflags(ios::left); // 清除状态左对齐
    cout << setiosflags(ios::right); // 设置右对齐 <iomainp>中设置输出格式的标志字
    cout << 123.456789 << endl;// ****123.46
    cout << setiosflags(ios::left | ios::fixed); // 设左对齐,以固定小数位显示
    cout.precision(3);    // 设置实数显示三位小数
    cout << 999.123456 << endl;// 999.123
    cout << resetiosflags(ios::left | ios::fixed); //清除状态左对齐和定点格式
    cout << setiosflags(ios::left | ios::scientific); //设置左对齐,以科学技术法显示
    cout.precision(3);   //设置保留三位小数
    cout << 123.45678 << endl;// 1.235e+02
    return 0;
}

调用cin成员函数

C++ cin 输入流对象常用成员方法
成员方法名功能
getline(char *buf,int n)从输入流中的当前字符开始读取n-1个字符到缓冲区buf,或读到‘\n’为止,结尾自动添加结束标‘\0’
getline(char *buf,int n,char ch)读到字符ch为止,结尾自动添加‘\0’,ch为终止界定符
get()从键盘输入一个字符,ascii码形式,输入crl+z,再回车,返回EOF(文件结束符标记,常量,-1),同时该字符会从输入流中消失。
gcount()返回上次从输入流提取出的字符个数,该函数常和 get()、getline()、ignore()、peek()、read()、readsome()、putback() 和 unget() 联用。
peek()返回输入流中的第一个字符,但并不是提取该字符,只是读。可以返回空格和回车符,及文件结束符EOF.
putback©将字符 c 置入输入流(缓冲区)。
ignore(int n,char ch)跳过输入流中的n个字符,或跳过ch 及其之前的所有字符。默认为cin.ignore(1,EOF),跳过一个字符,该函数常用于跳过输入中无用的部分,以便提取有用的部分。
operator>>重载 >> 运算符,用于读取指定类型的数据,并返回输入流对象本身。
eof()判断输入流是否已经结束,返回值为true
实例
#include<iostream>
using namespace std;
int main()
{
    char val;
    val = cin.get();
    cout.put(val);//输入一个字母会返回一个相同字母
}

  1. C++ 编译器根据要输出变量的数据类型,选择合适的流插入运算符来显示值。所以,可以说用cout就不用管数据类型 ↩︎

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guangod

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值