1. 流
- 流:数据从一个对象到另一个对象的传输。
- 功能:标准输入输出+文件处理
分类 | 含义 |
---|---|
文本流 | 一串ASCII字符 |
二进制流 | 一串二进制 |
2. 流类型
标准库定义了三大类流类型:标准I/O流、文件流、字符串流
- 标准I/O流
ios
是抽象类ostream
是cout
、clog
、cerr
的类istream
是cin
的类
- 文件流类型
ifstream
从文件读取数据ofstream
向文件写入数据iofstream
文件读写数据
- 字符串流类型
istringstream
从string
读取数据ostringstream
向string
写入数据iostringstream
读写string
数据
(***)3. 流对象
(1)头文件:#incliude
#include
通常标准I/O流对象是全局对象不需要定义,而文件流对象和字符串流对象需要用户定义。
标准I/O流对象有以下四个:
No. | 全局流对象 | 名称 | 缓存 |
---|---|---|---|
1 | cout |
标准输出流 | 带缓存 |
2 | cin |
标准输入流 | 带缓存 |
3 | clog |
标准日志流 | 带缓存 |
4 | cerr |
标准错误流 | 无缓存 |
a. 项目中则是有定义的日志库
clog << "clog" << endl;//项目中则是有定义的日志库
b.流对象不能 对象示例化,调用copy
ostream os; //流对象不能 对象示例化,调用copy
c.流对象不能赋值;调用赋值运算符
os = cout; //流对象不能赋值;调用赋值运算符
(完整代码001_stream.cpp)
#include <iostream>
using namespace std;
void Func(ostream os){
os << "Hello" << endl;
}
int main(){
cout << "cout" << endl;
clog << "clog" << endl;//项目中则是有定义的日志库
cerr << "cerr" << endl;
//Func(cout);
//ostream os; 流对象不能 对象示例化,调用copy
//os = cout; //流对象不能赋值;调用赋值运算符
}
注意:流对象通常都不能复制,即不能调用标准库的流对象的拷贝构造函数;
4. 流对象状态
流对象状态在某一个时刻必定处于以下四个状态之一。
No. | 状态 | 含义 |
---|---|---|
1 | good() |
前一个流操作成功 |
2 | eof() |
到输入尾/文件尾 |
3 | fail() |
发生意外事情(读取失败) |
4 | bad() |
发生意外严重事情(磁盘读取失败) |
(***)5. I/O操作
I/O操作主要有如下五种:
- 输入操作:
in >> x
或者getline(in,s)
- 输出操作:
out << x
- 操作符
- 流状态
- 格式化
- 输出流默认设置
类型 | 进制 | 宽度(字符数目) | 对齐 | 填充 | 精度 |
---|---|---|---|---|---|
整数 | 十进制 | 0 | 右对齐 | 空格 | 1 |
实数 | 十进制 | 0 | 右对齐 | 空格 | 6位数 |
字符串 | - | 0 | 右对齐 | 空格 | 字符串实际长度 |
-
格式控制
-
格式控制成员函数
流对象.格式控制函数(实参)
-
预定义格式控制函数
预定义格式控制函数(实参)
-
流的输出控制格式
作用 | 格式控制成员函数 | 预定义格式控制函数 | 预定义格式控制符/操作子 | 效果持续 |
---|---|---|---|---|
进制 | flags() setf() unsetf() |
setiosflags() |
dec oct hex showbase |
能持续 |
宽度 | width(n) |
setw(n) |
- | 不能持续 |
对齐 | flags() setf() unsetf() |
setiosflags() |
ios::right ios::left ios::internal |
能持续 |
填充 | fill(c) |
setfill(c) |
- | 能持续 |
精度 | precision(n) |
setprecision(n) |
- | 能持续 |
方案1:预定意控制符
(a)设置宽度+对齐+填充:
cout.flags(ios::internal); //插入对齐
cout.fill('&'); //填充
cout.width(8); //宽度需要多次设置;不连续
(完整代码002_format.cpp)
#include <iostream>
using namespace std;
int main(){
int n = -8;
float f = 8.8;
string str = "888";
cout.flags(ios::internal); //插入对齐
cout.fill('&'); //填充
cout.width(8); //宽度需要多次设置;不连续
cout << n << endl;
cout.width(8);
cout << f << endl;
cout.width(8);
cout << str << endl;
}
(b)设置进制(仅仅影响整数,不影响浮点数);
cout.flags(ios::hex);
设置精度(主要影响浮点数),默认:整数+小数一共六位;
(如果设定大于现在,则适应);
cout.precision(10);
cout<<3.1415<<endl; //3.1415
如果小于,转化成科学记数法;
cout.precision(2);
cout<<3.1415<<endl; //3.1
设置小数点后面位数的做法;
cout.precision(5);
cout.flags(ios::fixed);
cout << 5.0 << endl;
(完整代码 003_format.cpp)
#include <iostream>
using namespace std;
int main(){
int n = 8;
float f = 8.8;
string str = "888";
cout.flags(ios::right);
cout.fill('&');
cout.flags(ios::oct);
cout.width(8);
cout << n << endl;
cout.width(8);
cout << f << endl;
cout.width(8);
cout << str << endl;
//cout.precision(10);
//cout<<3.1415<<endl;
//cout.precision(2);
//cout<<3.1415<<endl;
cout.precision(5);
cout.flags(ios::fixed);
cout << 5.0 << endl;
}
方案2:预定意格式控制函数
a.预定义格式控制函数的头文件
#include <iomanip> //a.预定义格式控制函数的头文件
b.必须设置长度才能看到其他填充的信息0.01****
cout << setw(10) << f<<endl; //b.必须设置长度才能看到其他填充的信息0.01****
c.小数点后两位的设置;
cout << setw(10)<< setprecision(2) << fixedsh << 1113.14523 <<endl; //c.小数点后两位的设置;
d. showbase--基础进制,uppercase(大写)
cout << setw(10) << setfill('*') << left << hex<<showbase << uppercase<< n <<endl; //showbase--基础进制,uppercase(大写)
(完整代码 004_format_func.cpp)
#include <iostream>
#include <iomanip> //a.预定义格式控制函数的头文件
using namespace std;
int main(){
int n = 10;
float f = 0.01;
string s = "Hell0";
cout << setw(10) << setfill('*') << left << hex<<showbase << uppercase<< n <<endl; //showbase--基础进制,uppercase(大写)
cout << setw(10) << f<<endl; //b.必须设置长度才能看到其他填充的信息0.01****
cout << setw(10) << s <<endl;
cout << setw(10)<< setprecision(2) << fixed << 1113.14523 <<endl; //c.小数点后两位的设置;
}
方案3:可以混合使用
- 流的输出控制格式:
dec
oct
hex
(10,8,16) - 数据输入成员函数
字符输入成员函数:get()
字符串输入成员函数:getline()
- 数据输出成员函数:
put()
(***)6.stringstream
6.1 字符串转化数字
(1)(输入输出流运算符重载)
ostream& operator<<(ostream& os,const Simple& s){
return os << s.GetN() << endl;
}
istream& operator>>(istream& is,Simple& s){
int n;
is >> n;
s.SetN(n);
return is;
}
(2)原理,亦可以直接调用函数
int Stoi(const string& s){
//(1.1)字符串转化为数字的函数原型
istringstream iss(s);
int n;
iss >> n;
return n;
}
C++11提供如下函数简化字符串转数字
-
stoi()
stol()
stoul()
stoll()
stoull()
//int ,long,longlong -
stof()
stod()
stold()
//float ,double ,long double
6.2 数字转化字符串
(1)(输入输出流运算符重载)
ostream& operator<<(ostream& os,const Simple& s){
return os << s.GetN() << endl;
}
istream& operator>>(istream& is,Simple& s){
int n;
is >> n;
s.SetN(n);
return is;
}
(2)原理
ostringstream oss;
oss << 4 << " " << 3.14 << " "<&