菜鸟笔记
提升您的技术认知

std::stringstream头文件及清空处理

std::stringstream 的头文件是 sstream.h,需要包含sstream 即#include

stringstream中clear函数并非清空缓存内容,需要使用str(“”)。

通过下面一段代码分析差异

#include<iostream>
#include"mulmsginfo.pb.h"
#include<memory>
#include<sstream>
using namespace std;
using namespace lgh::mulmsgtest;

#define USER_LIST_MAX_VALUE 5

int main()
{
    int initId = 1000;
    std::string initName("Da Bing");
    int initAge = 20;

    std::shared_ptr<mulmsgUserInfo> mmsptr(new mulmsgUserInfo());
    ::lgh::mulmsgtest::mulmsgUserInfo_userinfo* mulptr = NULL;

    std::stringstream ss_name;
    for(int i=0;i<USER_LIST_MAX_VALUE;i++)
    {
        mulptr = mmsptr->add_userinfolist();
        mulptr->set_id(initId);
        ss_name<<initName<<i;
        mulptr->set_name(ss_name.str());
        mulptr->set_age(initAge);

        initId++;
        ss_name.str("");//clear() is invalid
        initAge++;
    }

    std::shared_ptr<mulmsgUserInfo> outptr(mmsptr);
    ::google::protobuf::RepeatedPtrField<mulmsgUserInfo_userinfo>::iterator iter;
    ::google::protobuf::RepeatedPtrField<mulmsgUserInfo_userinfo> userlist = outptr->userinfolist();
    for(iter=userlist.begin();iter!=userlist.end();iter++)
    {
        cout<<"id : "<<iter->id()<<" ,name : "<<iter->name()<<" ,age : "<<iter->age()<<endl;
    }
    cout<<endl;

    return 0;
}

使用clear()的结果如下

test@linux:~/coding/protocolbuffer/repeatadd> g++ --std=c++11 mulmsginfo.pb.cc mulmsgmain.cpp -o mulmsgexc `pkg-config --cflags --libs protobuf` -pthread
test@linux:~/coding/protocolbuffer/repeatadd> ./mulmsgexc
id : 1000 ,name : Da Bing0 ,age : 20
id : 1001 ,name : Da Bing0Da Bing1 ,age : 21
id : 1002 ,name : Da Bing0Da Bing1Da Bing2 ,age : 22
id : 1003 ,name : Da Bing0Da Bing1Da Bing2Da Bing3 ,age : 23
id : 1004 ,name : Da Bing0Da Bing1Da Bing2Da Bing3Da Bing4 ,age : 24

改用str(“”)后,结果如下

test@linux:~/coding/protocolbuffer/repeatadd> g++ --std=c++11 mulmsginfo.pb.cc mulmsgmain.cpp -o mulmsgexc `pkg-config --cflags --libs protobuf` -pthread
test@linux:~/coding/protocolbuffer/repeatadd> ./mulmsgexc
id : 1000 ,name : Da Bing0 ,age : 20
id : 1001 ,name : Da Bing1 ,age : 21
id : 1002 ,name : Da Bing2 ,age : 22
id : 1003 ,name : Da Bing3 ,age : 23
id : 1004 ,name : Da Bing4 ,age : 24

总结

clear() 方法只是重置了stringstream的状态标志,并没有清空数据。如果需要清空数据,使用str(“”)来实现。否则,不仅结果达不到预期,而且还会无限消耗内存。

重复利用stringstream对象

如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用str(“”)方法;

在多次转换中重复使用同一个stringstream(而不是每次都创建一个新的对象)对象最大的好处在于效率。stringstream对象的构造和析构函数通常是非常耗费CPU时间的。

一些实例

#include <string>
#include <sstream>
#include <iostream> 

int main()
{
    std::stringstream stream;
    std::string result;
    int i = 1000;
    stream << i; //将int输入流
    stream >> result; //从stream中抽取前面插入的int值
    std::cout << result << std::endl; // print the string "1000"
}