学会思考
刻意练习

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

程序与外界环境的信息交换

当程序与外界环境进行信息交换时,存在着两个对象:程序中的对象,文件对象。

流是一种抽象,负责在数据的生产者和数据的消费者之间建立联系,并管理数据的流动;

 

流对象与文件操作

程序建立一个流对象

指定这个流对象与某个文件对象建立连接

程序操作流对象

流对象通过文件系统对所连接的文件对象产生作用

 

提取与插入

读操作在流数据抽象中被称为从流中提取;

写操作被称为向流中写入;

最重要的三个输出流:
ostream

ofstream

ostringstream

预先定义的输出流对象

cout标准输出

cerr标准错误输出,没有缓冲,发送给它的内容立即被输出

clog类似cerr,但是有缓冲,缓冲区慢了才输出;

 

标准输出换向

ofstream fout("b.out");

streambuf *pOld = cout.rdbuf(fout.rdbuf());

//...

cout.rdbuf(pOld);

 

构造输出流对象

ofstream myFile("filename");

或者

ofstream myFile;

myFile.open("filename");

备注:构造对象时或者用open打开文件时可以指定模式

ofstream myFile("filename",ios_base::out | ios_base::binary);

 

文件输出流成员函数的三种类型

与操作符等价的成员函数

执行非格式化写操作的成员函数

其他修改流状态且不同于操作符或者插入运算符的成员函数

 

文件输出流的成员函数

open函数:把流与特定的磁盘文件关联起来,需要指定打开模式;

put函数

把一个字符写到输出流中

write函数:把内存中的一块内容写到一个文件输出流中

seekp和tellp函数:操作文件流的内部指针

close函数:关闭与一个文件输出流关联的磁盘文件

错误处理函数:在写到一个流时进行错误处理

 

向文本文件输出

使用ofstream构造函数中的模式参量指定二进制输出模式

以通常方式构造一个流,然后使用setmode成员函数,在文件打开后改变模式;

通过二进制文件输出流对象完成输出

 

向二进制文件输出

#include <fstream>
using namespace std;

struct Date {
    int mon, day, year;
};

int main()
{
    Data dt = { 6,8,98};
    ofstream file("data.dat", ios_base::binary);
    file.write(reinterpret_cast<char *>(&dt), sizeof(dt));
    file.close();
    return 0;
}

 

向字符串输出

将字符串作为输出流的目标,可以实现将其他数据类型转换为字符串的功能

字符串输出流(ostringstream)

用于构造字符串

支持ofstream类的除open,close外的所有操作;

str函数可以返回当前已构造的字符串

典型应用:将数值转化为字符串

 

使用ostringstream将数值转换为字符串

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

template <class T> inline string toString(const T &v)
{
    ostringstream os;
    os << v;
    return os.str();
}

int main()
{
    string str1 = toString(5);
    cout << str1 << endl;
    string str2 = toString(20.2);
    cout << str2 << endl;
    return 0;
}

 

输入流

  • istream类最适合用于顺序文本模式输入。cin是其实例。
  • ifstream类支持磁盘文件输入
  • 提取运算符(>>)对于所有标准C++数据类型都是预先设计好的

输入流相关函数

open把该流与一个特定磁盘文件相关联

get功能与提取运算符很像,主要的不同点是get函数在读入数据时包括空白字符

getline功能是从输入流中读取多个字符,并且允许指定输入终止符,读取完成后,从读取的内容中删除终止符;

 

read从一个文件读字节到一个指定的内存区域,由长度参数确定要读写的字节数。当遇到文件结束符或者在文本模式文件中遇到文件结束标记符时结束读取;

 

seekg用于设置文件输入流中读取数据位置的指针

tellg返回当前读指针的位置

close关闭与一个文件输入流关联的磁盘文件

//get函数使用举例
#include <iostream> 
using namespace std;
int main()
{
    char ch;
    while ((ch = cin.get() != EOF))
    {
        cout.put(ch);
    }
    return 0;
}
//为输入流指定一个终止符
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string line;
    cout << "Type a line terminated by 't' " << endl;
    getline(cin, line, 't');
    cout << line << endl;
    return 0;
}

例子:若在控制台输入“hello world”,则程序的输出是:(空格为终止符)

#include<iostream>
#include<string>
using namespace std;
int main(){
    string line;
    getline(cin, line, ' ');
    cout << line << endl;
    return 0;
}

从字符串输入

将字符串作为文本输入流的源,可以将字符串转换为其他类型

字符串输入流(istringstream)

用于从字符串读取数据

在构造函数中设置要读取的字符串

功能:

支持ifstream类的除open,close外的所有的操作;

//用istringstream将字符串转化为数值
template <class T> inline T fromString(const string &str)
{
    istringstream is(str);
    T v;
    is >> v;
    return v;
}

int main()
{
    int v1 = fromString<int>("5");
    cout << v1 << endl;
    double v2 = fromString<double>("1.2");
    cout << v2 << endl;
    return 0;
}

 

posted on 2017-03-18 22:15  Worty  阅读(517)  评论(0编辑  收藏  举报