00001 #ifndef H_XSTRING 00002 #define H_XSTRING 00003 00004 template<class E, class T=std::char_traits<E>, class A=std::allocator<E> > 00005 class basic_xstring : public std::basic_string<E,T,A> 00006 { 00007 typedef E value_type; 00008 typedef A allocator_type; 00009 typedef std::basic_string<E,T,A> parent; 00010 typedef basic_string<E,T,A> self; 00011 typedef typename parent::size_type size_type; 00012 public: 00013 basic_xstring(const value_type* ptr, size_type n, const allocator_type& al = allocator_type()) 00014 : parent(ptr,n,al) {} 00015 basic_xstring(const value_type* ptr, const allocator_type& al = allocator_type()) 00016 : parent(ptr,al) {} 00017 basic_xstring(const basic_xstring& s, size_type off = 0, size_type n = npos, const allocator_type& al = allocator_type()) 00018 : parent(s,off,n,al) {} 00019 basic_xstring(size_type n, value_type c, const allocator_type& al = allocator_type()) 00020 : parent(n,c,al) {} 00021 explicit basic_xstring(const allocator_type& al = allocator_type()) 00022 : parent(al) {} 00023 basic_xstring(const parent& p) : parent(p) {} 00024 template<class U> 00025 explicit basic_xstring(const U& u) 00026 { 00027 std::basic_ostringstream<E,T,A> os; 00028 os << u; 00029 *this=os.str(); 00030 } 00031 00032 operator const value_type* () { return c_str(); } 00033 int as_int() const 00034 { 00035 return atoi(c_str()); 00036 } 00037 00038 double as_double() const 00039 { 00040 return atof(c_str()); 00041 } 00042 00043 void trim_left() 00044 { 00045 int p=find_first_not_of(" \t\n\r"); 00046 if (p>0) *this=substr(p); 00047 } 00048 00049 void trim_right() 00050 { 00051 int p=find_last_not_of(" \t\n\r"); 00052 if (p>=0) 00053 *this=substr(0,p+1); 00054 } 00055 00056 void trim() 00057 { 00058 trim_left(); 00059 trim_right(); 00060 } 00061 00062 bool read_line(std::istream& is) 00063 { 00064 *this=""; 00065 if (is.eof()) return false; 00066 char buffer[1024]; 00067 while (true) 00068 { 00069 is.getline(buffer,1000); 00070 if (is.eof()) return !empty(); 00071 xstring s=buffer; 00072 *this+=s; 00073 if (s.length()<1000) return !empty(); 00074 } 00075 } 00076 }; 00077 00078 template<class T> 00079 class basic_string_tokenizer 00080 { 00081 typedef basic_xstring<T> str; 00082 typedef std::vector<str> seq; 00083 seq m_Tokens; 00084 unsigned m_Current; 00085 public: 00086 basic_string_tokenizer(const str& s, const str& delim=" \t") 00087 : m_Current(0) 00088 { 00089 int p=-1; 00090 int len=s.length(); 00091 while (true) 00092 { 00093 p=s.find_first_not_of(delim,p+1); 00094 if (p<0) break; 00095 int e=s.find_first_of(delim,p+1); 00096 if (e<0) e=len; 00097 m_Tokens.push_back(s.substr(p,e-p)); 00098 p=e; 00099 } 00100 } 00101 00102 unsigned size() const { return m_Tokens.size(); } 00103 bool has_more_tokens() const { return m_Current<m_Tokens.size(); } 00104 str get_next_token() { return m_Tokens[m_Current++]; } 00105 }; 00106 00107 typedef basic_xstring<char> xstring; 00108 typedef basic_string_tokenizer<char> xstring_tokenizer; 00109 00110 inline void make_lower(xstring& s) 00111 { 00112 xstring::iterator b=s.begin(),e=s.end(); 00113 for(;b!=e;++b) 00114 { 00115 char& c=*b; 00116 if (c>='A' && c<='Z') c+=32; 00117 } 00118 } 00119 00120 00121 #endif // H_XSTRING 00122