扩展C++ string类
在实际开发过程中,C++string类使用起来有很多不方便的地方,笔者根据根据这些不足简单的扩展了这个类,如增加与数字之间的相互转化和格式化字符串。不足的地方望指正。读者也可以根据自己需求继续扩展。
头文件:exstring.h
- /*
- Author: wuqiang
- Email: debugroot@126.com
- Description:exstring is a subclass of basic_string.It is added some userful
- operations,such as toUpper,toLower,toNumber,fromNumber,format,etc.It can also
- convert between basic_string seamlessly,which is very important for compatibility.
- And it is almostly a wrapper of some C++ standard library,so there should be no bugs.
- If you find some,please let me known.It is totally free,you can use it in any way you desire.
- */
- #pragma once
- #include <string>
- #include <stdarg.h>
- #include <algorithm>
- #include <sstream>
- #include <iomanip>
- using namespace std;
- #ifndef INLINE
- #define INLINE inline
- #endif //INLINE
- static ios_base::fmtflags BaseFlag(int base)
- {
- return (base == 16) ? (ios_base::hex) :
- ( (base == 8) ? (ios_base::oct) : (ios_base::dec) );
- }
- template<class _Elem> struct ex_char_traits
- {
- };
- template<> struct ex_char_traits<char>
- {
- static INLINE int ct_vscprintf(const char* format, va_list argptr )
- {
- return _vscprintf(format, argptr);
- }
- static INLINE int ct_vstprintf_s(char* buffer, size_t numberOfElements,
- const char* format, va_list argptr)
- {
- return vsprintf_s(buffer, numberOfElements, format, argptr);
- }
- };
- template<> struct ex_char_traits<wchar_t>
- {
- static INLINE int ct_vscprintf(const wchar_t* format, va_list argptr )
- {
- return _vscwprintf(format, argptr);
- }
- static INLINE int ct_vstprintf_s(wchar_t* buffer, size_t numberOfElements,
- const wchar_t* format, va_list argptr)
- {
- return vswprintf_s(buffer, numberOfElements, format, argptr);
- }
- };
- template<class _Elem, class _Traits, class _Ax, class Type>
- Type ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
- Type t, int base)
- {
- ss.setf(BaseFlag(base), ios_base::basefield);
- ss >> t;
- return t;
- }
- template<class _Elem, class _Traits, class _Ax>
- float ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
- float t, int/*ignore base*/)
- {
- ss >> t;
- return t;
- }
- template<class _Elem, class _Traits, class _Ax>
- double ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
- double t, int/*ignore base*/)
- {
- ss >> t;
- return t;
- }
- template<class _Elem, class _Traits, class _Ax, class _ExTraits>
- class basic_exstring : public basic_string<_Elem, _Traits, _Ax>
- {
- public:
- typedef basic_exstring<_Elem, _Traits, _Ax, _ExTraits> _Myt;
- typedef basic_string<_Elem, _Traits, _Ax> _Mybase;
- #pragma region "constructor"
- //所有构造函数的行为同basic_string
- explicit INLINE _Myt(const _Ax& al = _Ax())
- :_Mybase(al)
- {
- }
- INLINE _Myt(const _Myt& rhs)
- :_Mybase(rhs)
- {
- }
- INLINE _Myt(const _Myt& rhs, size_type pos, size_type n,const _Ax& al = _Ax())
- :_Mybase(rhs, pos, n, al)
- {
- }
- INLINE _Myt(const _Elem *s, size_type n, const _Ax& al = _Ax())
- :_Mybase(s, n, al)
- {
- }
- INLINE _Myt(const _Elem *s, const _Ax& al = _Ax())
- :_Mybase(s, al)
- {
- }
- INLINE _Myt(size_type n, _Elem c, const _Ax& al = _Ax())
- :_Mybase(n, c, al)
- {
- }
- INLINE _Myt(const_iterator first, const_iterator last,const _Ax& al = _Ax())
- :_Mybase(first, last, al)
- {
- }
- //string(wstring)转化为exstring(exwstring)
- INLINE _Myt(const _Mybase& base)
- :_Mybase(base)
- {
- }
- #pragma endregion //constructor
- #pragma region "general operation"
- //所有字符转为大写,改变自身
- _Myt& toUpper()
- {
- transform(begin(), end(), begin(), toupper);
- return *this;
- }
- //所有字符转为大写,不改变自身
- _Myt toUpper() const
- {
- _Myt s;
- transform(begin(), end(), s.begin(), toupper);
- return s;
- }
- //所有字符转为小写,改变自身
- _Myt& toLower()
- {
- transform(begin(), end(), begin(), tolower);
- return *this;
- }
- //所有字符转为大写,不改变自身
- _Myt toLower() const
- {
- _Myt s(_Mysize, _Elem());
- transform(begin(), end(), s.begin(), tolower);
- return s;
- }
- //将所有oldStr替换为newStr
- _Myt& replace(const _Myt& oldStr, const _Myt& newStr)
- {
- if (oldStr.empty())
- return *this;
- size_type index;
- while ( (index = find(oldStr)) != npos )
- _Mybase::replace(index, oldStr.size(), newStr);
- return *this;
- }
- //删除左边所有包含在target中的字符
- _Myt& trimLeft(const _Myt& target)
- {
- while (!empty() && (target.find(*begin()) != npos))
- erase(begin());
- return *this;
- }
- //删除右边所有包含在target中的字符
- _Myt& trimRight(const _Myt& target)
- {
- while (!empty() && target.find(*rbegin()) != npos)
- erase(--end());
- return *this;
- }
- //返回左边count个字符,count大于总长度则返回整个字符串
- _Myt left(size_type count) const
- {
- return substr( 0, count );
- }
- //返回右边count个字符,count大于总长度则返回整个字符串
- _Myt right(size_type count) const
- {
- return substr( _Mysize < count ? 0 : _Mysize - count );
- }
- //忽略大小写判断两个字符串是否相等
- int compareNoCase(const _Myt& rhs) const
- {
- return toLower().compare(rhs.toLower());
- }
- //判断字符串是否以制定字符串开头
- bool beginWith(const _Myt& rhs) const
- {
- return find(rhs) == size_type(0);
- }
- //判断字符串是否以制定字符串结尾
- bool endWith(const _Myt& rhs) const
- {
- if(rhs.size() > _Mysize)
- return false;
- return compare(_Mysize - rhs.size(), rhs.size(), rhs) == 0;
- }
- #pragma endregion //general operation
- #pragma region "convert between numbers"
- //将字符串转为数字
- //base:进制数。可以为8,10,16,如果其它值则强制为10。浮点数则忽略此参数
- template<typename T>
- T toNumber (int base = 10) const
- {
- T t = T();
- basic_stringstream<_Elem, _Traits, _Ax> ss(_Myptr());
- return ConvertToNumber<_Elem, _Traits, _Ax>(ss, t, base);
- }
- //将整数转化为字符串
- //base:进制数。可以为8,10,16,如果其它值则强制为10
- template<typename T>
- static _Myt fromNumber ( T number, int base = 10 )
- {
- basic_stringstream<_Elem, _Traits, _Ax> ss;
- ss.setf(BaseFlag(base), ios_base::basefield);
- ss << number;
- return ss.str();
- }
- //将float转化为字符串
- //f:格式化参数。可以为'f','e','E','g','G'。'f'为定点数,'e'或'E'表示科学计数法
- // 'g'或‘G’表示格式化为定点数或科学计数法,看哪一个表示方便。
- //prec:小数点后的位数(定点数表示法)或总的有效位数(科学计数法)
- static _Myt fromNumber ( float number, _Elem f = _Elem('g'), int prec = 6 )
- {
- return fromNumber(static_cast<double>(number), f, prec);
- }
- //将double转化为字符串,参数解释同上
- static _Myt fromNumber ( double number, _Elem f = _Elem('g'), int prec = 6 )
- {
- basic_stringstream<_Elem, _Traits, _Ax> ss;
- ss << setprecision(prec);
- if ( _Traits::eq(f, _Elem('f')) )
- ss << setiosflags(ios_base::fixed);
- else if ( _Traits::eq(f, _Elem('e')) || _Traits::eq(f, _Elem('E')) )
- ss << setiosflags(ios_base::scientific);
- ss << number;
- return ss.str();
- }
- #pragma endregion //convert between numbers
- #pragma region "format string"
- //将szFormat格式化为字符串,参数解释同sprintf
- void format(const _Elem* szFormat, ...)
- {
- if(!szFormat)
- return;
- va_list argList;
- va_start(argList, szFormat);
- formatV(szFormat, argList);
- va_end(argList);
- }
- //将szFormat格式化为字符串,参数解释同sprintf
- void formatV(const _Elem* szFormat, va_list argList)
- {
- if(!szFormat)
- return;
- int nLength = _ExTraits::ct_vscprintf(szFormat, argList);
- if(nLength < 0)
- return;
- resize(nLength);
- _ExTraits::ct_vstprintf_s(_Myptr(), nLength + 1, szFormat, argList);
- va_end(argList);
- }
- #pragma endregion //format string
- };
- typedef basic_exstring<char, char_traits<char>,
- allocator<char>, ex_char_traits<char> > exstring;
- typedef basic_exstring<wchar_t, char_traits<wchar_t>,
- allocator<wchar_t>, ex_char_traits<wchar_t> > exwstring;
使用举例:
- #include <iostream>
- #include <tchar.h>
- #include "exstring.h"
- #ifdef _UNICODE
- typedef exwstring tstring;
- #define tcout wcout
- #else
- typedef exstring tstring;
- #define tcout cout
- #endif //_UNICODE
- int main(int argc, char* argv[])
- {
- tstring s(_T("\t Hello ExString\r\n"));
- tcout << _T("result of triming left:") << s.trimLeft(_T("\t ")) << endl;
- tcout << _T("result of triming right:") << s.trimRight(_T("\r\n")) << endl;
- tcout << _T("result of compare") << s.compareNoCase(_T("hello exstring")) << endl;
- tcout << _T("result of converting to upper:") << s.toUpper() << endl;
- tcout << _T("result of converting to lower:") << s.toLower() << endl;
- tcout << _T("the left 5 chars:") << s.left(5) << endl;
- tcout << _T("the right 8 chars:") << s.right(8) << endl;
- tcout << _T("result of appending:") << s.append(_T(",exstring is practical")) << endl;
- tcout << _T("result of replacing:") << s.replace(_T("exstring"), _T("Exstring")) << endl;
- s.format(_T("sizeof(%s) is %d(0x%x)"), _T("exstring"), sizeof(exstring), sizeof(exstring));
- tcout << _T("result of formating:") << s << endl;
- tcout << tstring(_T("0xFF")).toNumber<int>(16) << endl;
- tcout << tstring(_T("-1")).toNumber<unsigned __int64>() << endl;
- tcout << tstring(_T("12.3456789")).toNumber<float>() << endl;
- tcout << tstring::fromNumber(255) << endl;
- tcout << _T("0x") << tstring::fromNumber(__int64(-1), 16).toUpper() << endl;
- tcout << tstring::fromNumber(12.3456789, _T('f'), 4) << endl;
- tcout << tstring::fromNumber(12.3456789, _T('E'), 4) << endl;
- return 0;
- }
输出:
http://blog.csdn.net/passion_wu128/article/details/38354541
扩展C++ string类的更多相关文章
- ASP.Net string 类的扩展方法 [转]
string 类的扩展方法列表(基本相同于 IEnumerable<T> 接口的成员列表): Aggregate<> //累加 All<> / ...
- Java基础篇(02):特殊的String类,和相关扩展API
本文源码:GitHub·点这里 || GitEE·点这里 一.String类简介 1.基础简介 字符串是一个特殊的数据类型,属于引用类型.String类在Java中使用关键字final修饰,所以这个类 ...
- 原生js的String类扩展
文章转自:http://www.cnblogs.com/zfc2201/archive/2012/12/16/2820335.html JS String类拓展方法: //获取字符数组 String. ...
- [Swift]扩展String类:extension String
请参考本博客另一篇技术博文: <[Swift]字符串(String类.NSString类)常用操作> extension String { //获取字符串首字符 var first: St ...
- 电话号码 马赛克*号 string类扩展
/// <summary> /// 字符串马赛克 /// </summary> /// <param name="source"></pa ...
- [Swift]扩展String类:实现find()查找子字符串在父字符串中的位置
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- C/C++关于string.h头文件和string类
学习C语言时,用字符串的函数例如stpcpy().strcat().strcmp()等,要包含头文件string.h 学习C++后,C++有字符串的标准类string,string类也有很多方法,用s ...
- C#部分---arraylist集合、arraylist集合中的object数据转换成int类string类等;间隔时间的表示方法;
ArrayList和Array的区别: 相同点:1.两者都实现了IList.ICollection.IEnumerable接口: 2.两者都可以使用证书索引访问集合中的元素,包括读取和赋值 ...
- Javascript String类的属性及方法
String 类 Attribute and method anchor() 创建一个<a>标签的实例,将其name属性设置为被传递给此方法的字符串 big() ...
随机推荐
- 关于“创业者与VC见面的10个不成文细节点”
著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:Will Wang链接:http://www.zhihu.com/question/19641135/answer/50974 ...
- Ubuntu下QT控制台程序无法运行的解决方案以及XTerm的配置方法
Ubuntu下QT控制台程序无法运行的解决方案以及XTerm的配置方法 最近由于老师要求要在Ubuntu下QT上进程多线程服务器的开发,虽然只是单纯的调用qt的network模块,但是为了避免麻烦,我 ...
- #include <fstream>
1 fstream 2 ifstream 3 ofstream 4 seekg 5 seekp 6 tellg 7 tellp 1 fstream 打开输入输出文件流 #include <ios ...
- Freedur为什么会免费?
难道没人看看他们的官方站点吗? Freedur倒闭了...... 一个中国人,Chris Lee,作为Freedur的会计师,窃取了公司的银行帐号.并将Freedur的官方站点指向自己的空间.而且声称 ...
- 纯CSS3实现自定义涂鸦风格的边框
今天我们要来分享一款基于纯CSS3的自定义边框应用,看上去它像一个Tooltip控件,因为下边框有一个小三角,就像很多地方的引用文本框一样.另外这款CSS3边框是涂鸦风格的,看起来很有个性.用CSS3 ...
- AutoResetEvent和ManualResetEvent
本文在于巩固基础 AutoResetEvent 概念:通知正在等待的线程已发生的事件 如果AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set 来通知资 ...
- 常用的sql server规范
常见的字段类型选择1.字符类型建议采用varchar/nvarchar数据类型2.金额货币建议采用money数据类型3.科学计数建议采用numeric数据类型4. 自增长标识建议采用bigint数据类 ...
- ZOJ3784 String of Infinity 高大上的AC自动机 数据原来这么水啊!不算输入输出只有5-7行
找给定s集合里面word全部是同一个字符的,这样的word有几个,如果数量<m就yes,否则就no.#include<iostream> #include<cstring> ...
- Egret及Node.js的安装部署
最近在学Html5游戏开发,我选择的是国内的一个游戏开发框架egret.因为涉及到node.js这个近年来新兴起来的技术.借此机会把这方面知识学习一下. node.js以及egret的操作类似于Lin ...
- Windows Server 2008 安装好之后的简单配置
1.禁用密码复杂度 在运行中输入GPEDIT.MSC 打开组策略,找到计算机配置->Windows设置->安全设置->账户策略中的密码策略,将“密码必须符合复杂性要求”设置为禁用即可 ...