mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
stringUtils.hpp
Go to the documentation of this file.
1 /** \file stringUtils.hpp
2  * \brief Utilities for working with strings
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup stringutils
7  *
8  */
9 
10 //***********************************************************************//
11 // Copyright 2015, 2016, 2017 Jared R. Males (jaredmales@gmail.com)
12 //
13 // This file is part of mxlib.
14 //
15 // mxlib is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 // mxlib is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU General Public License for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
27 //***********************************************************************//
28 
29 #ifndef ioutils_stringUtils_hpp
30 #define ioutils_stringUtils_hpp
31 
32 
33 #include <string>
34 #include <sstream>
35 #include <vector>
36 #include <limits>
37 #include <algorithm>
38 
39 #include "../mxlib.hpp"
40 
41 namespace mx
42 {
43 namespace ioutils
44 {
45 
46 /** \addtogroup stringutils
47  * @{
48  */
49 
50 ///Convert a numerical value to a string
51 /** The default version uses the stream library to convert. A specialization is provided to prevent conversion of std::string.
52  *
53  * The precision parameter is only used for floating point types. If the default precision==0 is passed, then the maximum useful precision is
54  * used, from the value of std::numeric_limits<typeT>::max_digits10.
55  *
56  * The width and pad template parameters can be used to set a fixed maximum width and a pad character.
57  *
58  * Examples:
59  *
60  * To convert a double precision number to string:
61  * \code
62  double d = 2.898434;
63  std::string str;
64  str = convertToString(d); //note that you will not normally need to specify <typeT>
65  * \endcode
66  *
67  * To produce a fixed width 0 padded string from an integer:
68  * \code
69  int i = 23;
70  std::string str;
71  str = convertToString<int, 5, '0'>(i); //result is "00023".
72  * \endcode
73  *
74  * \tparam typeT is the type of value to convert
75  * \tparam width specifies the maximum width, not including the '\0'
76  * \tparam pad specifies the pad character
77  *
78  * \returns a string representation of value
79  *
80  */
81 template< typename typeT, unsigned width=0, char pad=' '>
82 std::string convertToString( const typeT & value, ///< [in] the value of type typeT to be converted
83  int precision = 0 ///< [in] [optional] the precision (see http://www.cplusplus.com/reference/ios/ios_base/precision/) to use for floating point types.
84  )
85 {
86 
87  std::ostringstream convert;
88 
89  if( std::is_floating_point<typeT>::value )
90  {
91  if(precision == 0 )
92  {
93  convert.precision( std::numeric_limits<typeT>::max_digits10);
94  }
95  else
96  {
97  convert.precision(precision);
98  }
99  }
100 
101  convert << value;
102 
103  if(width == 0)
104  {
105  return convert.str();
106  }
107  else
108  {
109  std::string c = convert.str();
110 
111  if( c.length() > width )
112  {
113  c.erase( width, c.length()-width);
114  return c;
115  }
116 
117  return std::string( width-c.length(), pad) + c;
118  }
119 
120 
121 
122 
123 }
124 
125 // Specialization of convertToString to avoid converting a string to a string
126 template<>
127 std::string convertToString<std::string>( const std::string & value,
128  int precision
129  );
130 
131 
132 /// Convert a string to a numerical value.
133 /** The default version attempts to do the conversion with a simple c style cast. Template specializations
134  * handle conversions to the basic types.
135  *
136  * Example:
137  * \code
138  * std::string str = "2.34567";
139  * double d;
140  * d = convertFromString<double>(str);
141  * \endcode
142  *
143  * \tparam typeT is the type of the numerical value desired
144  *
145  * \returns the converted numerical value.
146  */
147 template<typename typeT>
148 typeT convertFromString( const std::string & str /**< [in] is the string to convert*/ )
149 {
150  //If no specialization exists, we try to cast
151  return (typeT) str;
152 }
153 
154 template<>
155 char convertFromString<char>(const std::string & str /* [in] is the string to convert*/ );
156 
157 template<>
158 char16_t convertFromString<char16_t>(const std::string & str /* [in] is the string to convert*/ );
159 
160 template<>
161 char32_t convertFromString<char32_t>(const std::string & str /* [in] is the string to convert*/ );
162 
163 template<>
164 wchar_t convertFromString<wchar_t>(const std::string & str /* [in] is the string to convert*/ );
165 
166 template<>
167 signed char convertFromString<signed char>(const std::string & str /* [in] is the string to convert*/ );
168 
169 template<>
170 unsigned char convertFromString<unsigned char>(const std::string & str /* [in] is the string to convert*/ );
171 
172 template<>
173 short convertFromString<short>(const std::string & str /* [in] is the string to convert*/ );
174 
175 template<>
176 unsigned short convertFromString<unsigned short>(const std::string & str /* [in] is the string to convert*/ );
177 
178 template<>
179 int convertFromString<int>(const std::string & str /* [in] is the string to convert*/ );
180 
181 template<>
182 unsigned int convertFromString<unsigned int>(const std::string & str /* [in] is the string to convert*/ );
183 
184 template<>
185 long convertFromString<long>(const std::string & str /* [in] is the string to convert*/ );
186 
187 template<>
188 unsigned long convertFromString<unsigned long>(const std::string & str /* [in] is the string to convert*/ );
189 
190 template<>
191 long long convertFromString<long long>(const std::string & str /* [in] is the string to convert*/ );
192 
193 template<>
194 unsigned long long convertFromString<unsigned long long>(const std::string & str /* [in] is the string to convert*/ );
195 
196 template<>
197 float convertFromString<float>(const std::string & str /* [in] is the string to convert*/ );
198 
199 template<>
200 double convertFromString<double>(const std::string & str /* [in] is the string to convert*/ );
201 
202 template<>
203 long double convertFromString<long double>(const std::string & str /* [in] is the string to convert*/ );
204 
205 
206 /// Template specialization of convertFromString for bool
207 /** First looks for 0/1, f/t, or F/T in the first non-space character of str.
208  * Otherwise, we use convertFromString<int>.
209  *
210  * \returns the converted numerical value.
211  */
212 template<>
213 bool convertFromString<bool>(const std::string & str /**< [in] is the string to convert*/ );
214 
215 
216 /// Convert a string to all lower case.
217 /** Calls the c tolower function for each character in instr.
218  *
219  */
220 void toLower( std::string &outstr, ///< [out] will be resized and populated with the lower case characters
221  const std::string & instr ///< [in] is the string to convert
222  );
223 
224 /// Convert a string to all lower case.
225 /** Calls the c tolower function for each character in instr.
226  *
227  *
228  * \return the all lower case string
229  */
230 std::string toLower(const std::string & instr /**< [in] is the string to convert*/ );
231 
232 /// Convert a string to all upper case.
233 /** Calls the c toupper function for each character in instr.
234  *
235  */
236 void toUpper( std::string &outstr, ///< [out] will be resized and populated with the lower case characters
237  const std::string & instr ///< [in] is the string to convert
238  );
239 
240 /// Convert a string to all upper case.
241 /** Calls the c toupper function for each character in instr.
242  *
243  *
244  * \return the all lower case string
245  */
246 std::string toUpper(const std::string & instr /**< [in] is the string to convert*/ );
247 
248 ///Remove all white space from a string.
249 /**
250  * Uses std::remove_if.
251  */
252 void removeWhiteSpace( std::string & outstr, ///< [out] will contain the new string with no whitespace.
253  const std::string & instr ///< [in] is the string to remove whitespace from
254  );
255 
256 ///Remove all white space from a string.
257 /**
258  * Uses std::remove_if.
259  *
260  * \returns the modified string.
261  */
262 std::string removeWhiteSpace( const std::string & instr /**< [in] is the string to remove whitespace from*/ );
263 
264 /// Wrap a string by breaking it into smaller sized portions of a desired width
265 /** Whenever possible breaks at spaces. A single space is discarded at the break.
266  */
267 int stringWrap( std::vector<std::string> & lines, ///< [out] each new entry contains a wrapped portion of the string. Not cleared, so can accumulate.
268  const std::string & str, ///< [in] the string to wrap
269  int width ///< [in] the maximum width of the output strings
270  );
271 
272 /// Parses a string into a vector of tokens delimited by a character
273 /** E.g., the string
274  * \code
275  std::string s={"0,1,2,3,4"};
276  std::vector<int> v;
277  parseStringVector(v,s);
278  \endcode
279  * is parsed to a vector as if it was initialized with
280  \code
281  std::vector<int> v = {0,1,2,3,4};
282  \endcode
283  *
284  * \tparam typeT the type to convert the tokens too.
285  */
286 template<typename typeT>
287 void parseStringVector( std::vector<typeT> & v, ///< [out] the vector holding the parsed and converted tokens. Is cleared.
288  const std::string & s, ///< [in] the string to parse
289  char delim = ',' ///< [in] [optional] the delimiter. Default is comma \p ','.
290  )
291 {
292  size_t st;
293  size_t com;
294 
295  st = 0;
296  com = s.find(delim, st);
297 
298  v.clear();
299 
300  while(com != std::string::npos)
301  {
302  v.push_back( convertFromString<typeT>(s.substr(st, com-st)) );
303  st = com + 1;
304  com = s.find(delim, st);
305  }
306  v.push_back( convertFromString<typeT>(s.substr(st, s.size()-st)));
307 
308 }
309 
310 /// Parses a string into a vector of tokens delimited by a set of characters
311 /** E.g., the string
312  * \code
313  std::string s={"0,1:2 3,4"};
314  std::vector<int> v;
315  parseStringVector(v, s, ",: ");
316  \endcode
317  * is parsed to a vector as if it was initialized with
318  \code
319  std::vector<int> v = {0,1,2,3,4};
320  \endcode
321  *
322  * \tparam typeT the type to convert the tokens too.
323  */
324 template<typename typeT>
325 void parseStringVector( std::vector<typeT> & v, ///< [out] the vector holding the parsed and converted tokens. Is cleared.
326  const std::string & s, ///< [in] the string to parse
327  const std::string & delims ///< [in] the delimiters.
328  )
329 {
330  size_t st;
331  size_t com;
332 
333  st = 0;
334  com = s.find_first_of(delims, st);
335 
336  v.clear();
337 
338  while(com != std::string::npos)
339  {
340  v.push_back( convertFromString<typeT>(s.substr(st, com-st)) );
341  st = com + 1;
342  com = s.find_first_of(delims, st);
343  }
344  v.push_back( convertFromString<typeT>(s.substr(st, s.size()-st)));
345 
346 }
347 /// @}
348 
349 } //namespace ioutils
350 } //namespace mx
351 
352 #endif //ioutils_stringUtils_hpp
constexpr units::realT c()
The speed of light.
Definition: constants.hpp:60
void parseStringVector(std::vector< typeT > &v, const std::string &s, const std::string &delims)
Parses a string into a vector of tokens delimited by a set of characters.
int stringWrap(std::vector< std::string > &lines, const std::string &str, int width)
Wrap a string by breaking it into smaller sized portions of a desired width.
std::string removeWhiteSpace(const std::string &instr)
Remove all white space from a string.
std::string convertToString(const typeT &value, int precision=0)
Convert a numerical value to a string.
Definition: stringUtils.hpp:82
typeT convertFromString(const std::string &str)
Convert a string to a numerical value.
bool convertFromString< bool >(const std::string &str)
Template specialization of convertFromString for bool.
std::string toUpper(const std::string &instr)
Convert a string to all upper case.
std::string toLower(const std::string &instr)
Convert a string to all lower case.
The mxlib c++ namespace.
Definition: mxError.hpp:107