C++知识2——流类库与输入输出

一:I/O流的概念及流类库结构

No.1 一些概念

流是一种抽象,它负责在数据的生产者和数据的消费者之间建立联系,并管理数据的流动。
程序将流对象看做文件对象的化身
一般意义下的读操作在流数据抽象中被称为(从流中)提取,写操作被称为(向流中)插入
本章中把别名所表示的模板实例称作类

No.2 输出流 ostream

预先定义的ostream类对象用来完成向标准设备的输出:
cout是标准输出流

cerr是标准错误输出流,没有缓冲,发送给他的内容立即输出
clog类似于cerr,但是有缓冲,缓冲区满时输出

No.3 输出流 ofstream

ofstream支持磁盘文件输出。如果需要一个只输出的磁盘文件,可以构造一个ofstream类的对象。

二:插入运算符和操纵符

No.1 一些基本函数的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*控制宽度之 cout.width(),
当有cout.width(10)时候,即设置域宽时,默认为右对齐.
需要iomanip头文件
*/
#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
double rec[3]={ 1.22 , 3.4345 , 8.23456};
for(int i=0 ; i<3 ; i++){
cout.width(10);
cout<<rec[i]<<endl;
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
左对齐:由程序的运行结果可以得出,开左对齐后,
如果不人为关闭左对齐,左对齐是一直有效的.

设置域宽的操作必须在使用的时候调用一次,调用之后如果下次不
加上这句话是运行后是不会设置域宽的

需要iomanip头文件
*/
#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
double rec[3]={ 1.22 , 3.4345 , 8.23456};
cout<<setiosflags(ios_base::left);//设置左对齐
//cout<<setiosflags(ios::left);//也可以设置左对齐
for(int i=0 ; i<3 ; i++){
cout.width(10);
cout<<rec[i]<<endl;
}
cout<<resetiosflags(ios_base::left);//取消左对齐
//cout<<resetiosflags(ios::left);取消左对齐
cout.width(10);
cout<<rec[1]<<endl;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
在开头设置之后一直可以有效
setfill('想要填充的字符')需要iomanip头文件
*/
#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
double rec[3]={ 1.22 , 3.4345 , 8.23456};
cout<<setfill('@');//填充
for(int i=0 ; i<3 ; i++){
cout.width(10);
cout<<rec[i]<<endl;
}
cout.width(10);
cout<<rec[1]<<endl;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
double rec[3]={ 1.22 , 3.4345 , 8.23456};
cout<<setiosflags(ios_base::fixed);/*不使用科学计数法 */
//cout<<setiosflags(ios_base::scientific);/*使用科学计数法,一位有效数字的浮点数*/
/*
两个代码也是设置一次之后,如果不人为改变都是会一直符合的,具有持久性
因为没有设置有效位数,所以精度值确定了总的有效位数
*/
for(int i=0 ; i<3 ; i++){
cout.width(10);
cout<<rec[i]<<endl;
}
cout.width(10);
cout<<rec[1]<<endl;
return 0;
}

写一次代码,但是具有持久性的:
左对齐setiosflags(ios_base::left)
填充setfill(‘@’)
cout<<setiosflags(ios_base::scientific)
cout<<setiosflags(ios_base::fixed)

No.2 文件输出流成员函数

ios_base::out与ios_base::binary的相同点:
如果硬盘上有所命名的文件,会把此文件删掉,重建新文件
ios_base::app:
用于在文件尾部追加数据,不会再开一个新的文件存储

No.3 put函数

1
2
cout.put('A');//精确地输出一个字符
cout<<'A';/*输出一个字符,但此前设置的宽度和填充方式在此起作用*/

No.4 write函数

1
2
file.write((char * )(&c),sizeof(c));
//file.write(地址,sizeof())字节数

No.5 错误处理函数

fail的功能及返回值:
如果出现一个不可恢复的错误或一个预期的条件,例如一个转换错误或文件未找到,则返回一个非0值。在用零参数调用clear之后,错误标记被清除。

三:题目整理

1:要进行文件的输出,除了包含头文件iostream外,还要包含fstream
2: important:
定义char p=”abcd”;能输出p的值(“abcd”的地址)的为:cout<<(void )p;
解析:
在C语言里,输出一个字符串的指针很方便,直接printf(“%p/n”,p);就输出了。
而在c++里的cout在输出字符串地址的时候,自动输出对应的字符串了,所以转换为void *类型,因为void类型的cout不知道怎么输出了,最后只能输出”abcd”的地址了
分析:如果是&p输出的是地址的地址并不是所要的”abcd”的地址