std::ostringstream输出流详解

一、简单介绍

ostringstream是C++的一个字符集操作模板类,定义在sstream.h头文件中。ostringstream类通常用于执行C风格的串流的输出操作,格式化字符串,避免申请大量的缓冲区,替代sprintf。

派生关系图:

二、ostringstream的基本使用

ostringstream的构造函数形式:
explicit ostringstream ( openmode which = ios_base::out );

explicit ostringstream ( const string & str, openmode which = ios_base::out );

有时候,我们需要格式化一个字符串,但通常并不知道需要多大的缓冲区。为了保险常常申请大量的缓冲区以防止缓冲区过小造成字符串无法全部存储。这时我们可以考虑使用ostringstream类,该类能够根据内容自动分配内存,并且其对内存的管理也是相当的到位。取得std::ostringstream里的内容可以通过str()和str(string&)成员函数。

三、注意事项

std::ostringstream::str()返回的是临时对象,不能对其直接操作。

例如会有如下误用:

const char *  pBuffer  =  oss.str().c_str();
注意pBuffer指向的内存已被析构!!

四、代码测试

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

void main()
{
    ostringstream ostr1; // 构造方式1
    ostringstream ostr2("abc"); // 构造方式2  

/*----------------------------------------------------------------------------
*** 方法str()将缓冲区的内容复制到一个string对象中,并返回
----------------------------------------------------------------------------*/
    ostr1 << "ostr1 " << 2012 << endl; // 格式化,此处endl也将格式化进ostr1中
    cout << ostr1.str();   

/*----------------------------------------------------------------------------
*** 建议:在用put()方法时,先查看当前put pointer的值,防止误写
----------------------------------------------------------------------------*/
    long curPos = ostr2.tellp(); //返回当前插入的索引位置(即put pointer的值),从0开始
    cout << "curPos = " << curPos << endl;  

    ostr2.seekp(2); // 手动设置put pointer的值
    ostr2.put(‘g‘);     // 在put pointer的位置上写入‘g‘,并将put pointer指向下一个字符位置
    cout << ostr2.str() << endl;  

/*----------------------------------------------------------------------------
*** 重复使用同一个ostringstream对象时,建议:
*** 1:调用clear()清除当前错误控制状态,其原型为 void clear (iostate state=goodbit);
*** 2:调用str("")将缓冲区清零,清除脏数据
----------------------------------------------------------------------------*/
    ostr2.clear();
    ostr2.str("");  

    cout << ostr2.str() << endl;
    ostr2.str("_def");
    cout << ostr2.str() << endl;
    ostr2 << "gggghh";    // 覆盖原有的数据,并自动增加缓冲区
    cout << ostr2.str() << endl;
    ostr2.str("");   // 若不加这句则运行时错误,因为_df所用空间小于gggghh,导致读取脏数据
    ostr2.str("_df");
    cout << ostr2.str() << endl;

    // 输出随机内存值,危险
    const char* buf = ostr2.str().c_str();
    cout << buf << endl;

    // 正确输出_df
    string ss = ostr2.str();
    const char *buffer = ss.c_str();
    cout << buffer << endl;
}

运行结果如下:

转自:http://blog.csdn.net/lanxuezaipiao/article/details/16358159

时间: 2024-10-27 11:42:54

std::ostringstream输出流详解的相关文章

【转载】C++中替代sprintf的std::ostringstream输出流详解

一.简单介绍 ostringstream是C++的一个字符集操作模板类,定义在sstream.h头文件中.ostringstream类通常用于执行C风格的串流的输出操作,格式化字符串,避免申请大量的缓冲区,替代sprintf. 派生关系图: 二.ostringstream的基本使用 ostringstream的构造函数形式:explicit ostringstream ( openmode which = ios_base::out ); explicit ostringstream ( con

C++11 std::chrono库详解

所谓的详解只不过是参考www.cplusplus.com的说明整理了一下,因为没发现别人有详细讲解. chrono是一个time library, 源于boost,现在已经是C++标准.话说今年似乎又要出新标准了,好期待啊! 要使用chrono库,需要#include<chrono>,其所有实现均在std::chrono namespace下.注意标准库里面的每个命名空间代表了一个独立的概念.所以下文中的概念均以命名空间的名字表示! chrono是一个模版库,使用简单,功能强大,只需要理解三个

std::string类详解

之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够.字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要.我们可以用 = 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?).我们尽可以把它看成是C++的基本数据类型. 标准模板库(STL)提供了一个std::string类,其是std::basic_string的一个特化,它是一个容器类,可把字符串当作普通类型来使用,并支持比

Java-IO 输入输出流详解

一.文件的编码               开发时一定要注意项目默认的编码!!!!!!!!               文件操作的时候一定要记得关闭!!!!!!!!        ASCII:美国标准信息交换码,用一个字节的7位可以表示一个字符        ISO8859-1:拉丁码表,西欧标准字符集,用一个字节的8位表示        GB2312:中文编码表,用两个字节来表示中文编码        GBK:中文编码表的升级,融合了更多表示中文文字符号        GB18030:GBK的

Java输入输出流详解

通过数据流.序列化和文件系统提供系统输入和输出. Java把这些不同来源和目标的数据都统一抽象为数据流.Java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象. 在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流. 1.1.Java流的分类 按流向分: 输入流: 程序可以从中读取数据的流.输出流: 程序能向其中写入数据的流. 按数据传输单

Java I/O输入输出流详解

一.文件的编码               开发时一定要注意项目默认的编码!!!!!!!!               文件操作的时候一定要记得关闭!!!!!!!!        ASCII:美国标准信息交换码,用一个字节的7位可以表示一个字符        ISO8859-1:拉丁码表,西欧标准字符集,用一个字节的8位表示        GB2312:中文编码表,用两个字节来表示中文编码        GBK:中文编码表的升级,融合了更多表示中文文字符号        GB18030:GBK的

转 Java输入输出流详解(非常详尽)

转  http://blog.csdn.net/zsw12013/article/details/6534619 通过数据流.序列化和文件系统提供系统输入和输出. Java把这些不同来源和目标的数据都统一抽象为数据流.Java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象. 在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流. 1.1.J

Java实现文件写入——IO流(输入输出流详解)

输入输出的重要性:     输入和输出功能是Java对程序处理数据能力的提高,Java以流的形式处理数据.流是一组有序的数据序列,根据操作的类型,分为输入流和输出流. 程序从输入流读取数据,向输出流写入数据.Java是面向对象的程序语言,每一个数据流都是一个对象,它们提供了各种支持“读入”与“写入”操作的流类. Java的输入输出功能来自java.io 包中的InputStream类.OutputStream类.Reader类和Writer类以及继承它们的各种子类. (一)解析文件处理的奥秘 1

C++11多线程——lock详解

C++11提供了两种管理锁的类 std::lock_guard:与mutex RAII相关,方便线程对互斥量上锁 std::unique_lock:   与mutex RAII相关,方便线程对互斥量上锁,相比std::lock_guard提供了更好的上锁和解锁控制 一 lock_guard详解 lock_guard是一个模板类:template<classMutex>class lock_guard; lock_guard对象通常用来管理某个锁(Lock)对象,与Mutex RALL相关,方便