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