关于std::stringsteam的clear与str方法
来源:互联网 发布:京东程序员待遇怎么样 编辑:程序博客网 时间:2024/06/16 02:25
最近在开发中需要用stringstream来进行时间的转换,结果遇到了一些麻烦,
啥也别说,请各位看段代码先。(翠花,上代码!)
#include <stdio.h>
#include <iostream>
#include <sstream>
using namespace std;
#include "boost/date_time/posix_time/posix_time.hpp"
using namespace boost::gregorian;
using namespace boost::posix_time;
#include <boost/thread/tss.hpp>
using namespace boost;
class CDateParser
{
public:
static time_t parseDate(conststring& s);
private:
static thread_specific_ptr<stringstream> m_ptr;
};
thread_specific_ptr<stringstream>CDateParser::m_ptr;
/**
* @brief Convert modify time string to time_tfor easy internal handling
* @param str Modify time string returned byHTTP server, e.g. "Fri, 18 Jul 2008 11:53:14 GMT"
* @return Corresponding time_t result
*/
time_t CDateParser::parseDate(const string& str)
{
if (m_ptr.get() == 0) {
stringstream*pss = new stringstream();
time_input_facet*timefacet = new time_input_facet("%a, %d %b %Y %H:%M:%S %z"); // will be automatically deleted by related locale object
pss->imbue(locale(pss->getloc(),timefacet));
m_ptr.reset(pss);
}
ptimep;
m_ptr->clear();
// m_ptr->str("");
*m_ptr<< str;
*m_ptr>> p;
if (m_ptr->fail()) {
cout<< "do not understand: "<< str << endl;
return 0;
}
tmt = to_tm(p);
return mktime(&t);
}
int main() {
stringstr;
time_tt;
str= "1 GMT";
t= CDateParser::parseDate(str);
cout<< ctime(&t) << endl;
str= "Fri, 18 Jul 2008 11:53:14 GMT";
t= CDateParser::parseDate(str);
cout<< ctime(&t) << endl;
str= "Sat, 19 Jul 2008 11:53:14 GMT";
t= CDateParser::parseDate(str);
cout<< ctime(&t) << endl;
}
其中用到了boost的date_time/thread(TSS),使用TSS主要是为了重用stringstream对象,同时又保证线程安全.
运行的结果与期望的大相径庭,竟然三个都是:donot understand.
为什么呢?答案就在clear,这个方法仅仅只重置了stringstream对象的状态标示,并不能清除其已有的内容;并且,stringstream还有很容易被忽视的问题:我们必须显式清空之前放入stringstream的内容,<<的内容不会在>>后就被扔掉了(确实也应该如此设计,不然的话basic_istream就不会有seekg这个方法了)。
下面的文章重点讨论了后面这个问题:
http://hi.baidu.com/xxai/blog/item/6d7bed038c0f52ef09fa934b.html
有了上面这些对于stringstream的认识之后,答案是很明显的,我们仅需要在clear后添加一行代码:
m_ptr->str("");
以清除stringstream先前的内容。
注意:clear是必须的,否则fail状态会在第一次失败后一直保持。
在解决这个问题的过程中分别向boostmaillist和googleC++ group提交了两个帖子,寻求帮助,googlegroups的帖子的链接如下:
http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/a334defcad5bbe9a#
虽然我在收到回复之前已经google出了答案,但是还是不得不佩服groups里的高人的严谨与热心,有兴趣的朋友可以去看看。
另:下面的链接包含了对stringstream的基本介绍:
http://www.cppblog.com/Sandywin/archive/2007/07/13/27984.html
最后补充两点:
1、static/global变量可以同时是TSS(TLS);
2、stringstream属于比较重量级的对象,如果需要频繁调用相关代码,则应考虑在多次调用间共享该对象。
如上面的parseDate实现与以下实现:
time_t CDateParser2::parseDate(const string& s) {
ptimep;
stringstreamss(s.c_str());
time_input_facet*timefacet = new time_input_facet("%a, %d %b %Y %H:%M:%S %z"); // will be automatically deleted by related locale object
ss.imbue(locale(locale::classic(),timefacet));
ss>> p;
tmt = to_tm(p);
return mktime(&t);
}
就存在极大的性能差别。
在笔者的环境下,100000次调用,共享stringstream只需23秒,而每次重建stringstream及相关对象的处理则需要19分19秒,二者执行效率竟相差50倍。(注:两种情况下CPU均维持在50%左右,Memory使用情况也相当)
- 关于std::stringsteam的clear与str方法
- stringstream clear与str("")的问题
- 关于char *str[]与 char str[]的区别
- 关于从std::vector中删除std::string的方法
- 关于电源管理:待机(Suspend,STR,挂起)/休眠(Hibernation,STD)问题的再讨论
- std::string 与 std::wstring 转换方法的效率比较
- List的Clear方法与RemoveAll方法用法小结
- 面试中回答关于oracle数据库优化的方法clear
- Parameters的clear方法
- Hibernate的clear方法
- Map的clear()方法
- stringstream中clear()和str(”“)的区别
- Clear Case 与Clear Quest的集成
- Clear Case 与Clear Quest的集成
- Hibernate Clear 与 Flush 方法
- 关于str.length()与font.stringWidth(str)的区别
- std::vector::clear
- std::vector::clear
- 在DELPHI程序中注册OLE/COM控件
- Java验证码资料精粹
- 一对多关系,按一聚合多
- 以数据库为中心的时代已经终结
- MySQL 常见错误提示的对照表
- 关于std::stringsteam的clear与str方法
- Coconn and XML
- 数据库中文问题总结
- asp.net操作Excel总结
- 数据库连接池的原理机制
- 纯虚函数的使用汇总
- Asp.Net 备份和恢复SQL SERVER 数据库
- Javascript的IE和Firefox兼容性汇编
- 基于Ajax.net的验证