C++ Iostreams 用法详解(四)缓冲区

续:

C++ Iostreams 用法详解(一)整体把握

C++ Iostreams 用法详解(二)标准入输出

C++ Iostreams 用法详解(三)状态标志位

期中考试终于告一段落,再来继续写咯。

在前面说到过每一个iostream对象都有一个缓冲区,我们称之为流缓冲区,那个这个所谓的流缓冲区是怎么存在的呢?iostreams中将该流缓冲区抽象为一个类,即streambuf类。

每个iostream的类都会包含一个指向streambuf对象的指针,这也就意味着我们可以直接的去访问到这个指针,并向该streambuf对象发送消息等(但是一般情况下我们并不需要这样做)。

既然说我们可以得到这个指针,那isotreams类当然会提供访问的接口了,这就是const成员函数rdbuf(),它会返回iostream对象所有的streambuf也就是缓冲区的指针。那这个缓冲区的指针有什么用呢?最常用的就是直接对其进行输入输出操作,看下面的例子:

1.txt内容:
hello world~~!!
my name is zorro.
nice to meet you~
int main() {
    ifstream fin("1.txt");
    cout << fin.rdbuf() << endl;
    system("pause");
    return 0;
}

上面的程序输出为:

image_thumb

可见对这个streambuf对象的指针进行输出操作,直接输出了缓冲区的所有内容,这是个很方便的功能。但是要注意的是,对rdbuf()返回的指针进行输出,一定得到的是整个缓冲区的内容吗?再看下面的例子:

int main() {
    ifstream fin("1.txt");
    string str;
    fin >> str;
    cout << fin.rdbuf() << endl;
    system("pause");
    return 0;
}

上面的程序输出为:

image_thumb[1]

可见对rdbuf()进行输出得到的并不一定是整个缓冲区的内容。为了对这个东西进行说明,我们必须先要了解缓冲区拥有的两个指针,我们一般称之为get指针和put指针。

对于streambuf类(其实就是basic_streambuf<char>类),可以看出它的操作是以字节(char)为单位的,所以get指针与put指针也是以字节为单位移动的。get指针指向的是缓冲区中下一个将要提取的字节,put指针指向的是向缓冲区中输出数据的下一个位置。可以通过成员函数seekg来移动get指针,seekp来移动put指针。当然从上面的描述我们可以看到,get指针是对输入的操作,put指针是对输出的操作,所以在类似ifstream这样的输入功能类中,是没有seekp函数只有seekg函数的,同样在ofstream也只有seekp函数没有seekg的。看下面的例子:

int main() {
    ifstream fin("1.txt");
    string str;
    fin >> str;
    fin.seekg(2,ios::beg);
    cout << fin.rdbuf() << endl;
    system("pause");
    return 0;
}

这个程序的输出为:

image_thumb[2]

可见对于rdbuf()返回的指针的输出,并不是直接输出缓冲区中的所有内容,而是输出get指针后面的内容。

iostream同样提供了成员函数tellg和tellp,这两个函数返回的是当前get指针和put指针的位置,返回的类型是streampos,它们同样很有用,可以用来临时存储一个位置。看下面的例子:

#define PRINTCURPOS(in) cout << "cur pos:" << in.tellg() << endl
#define PRINTANDEXEC(st) cout << #st << endl; st
int main() {
    PRINTANDEXEC(ifstream fin("1.txt"));
    PRINTANDEXEC(string str);
    PRINTCURPOS(fin);
    PRINTANDEXEC(fin >> str);
    PRINTCURPOS(fin);
    PRINTANDEXEC(fin.seekg(2,ios::beg));
    PRINTCURPOS(fin);
    PRINTANDEXEC(cout << fin.rdbuf() << endl);
    PRINTCURPOS(fin);
    system("pause");
    return 0;
}

上面的程序输出为:

image_thumb[3]

以上只演示了get指针的的使用,关于put指针的使用跟get指针差不多,就不赘述了。

posted @ 2013-05-28 10:32  mzorro  阅读(1700)  评论(0编辑  收藏  举报