StringManipulator.h
Go to the documentation of this file.
1 // StringManipulator.h
2 //
3 // David Adams
4 // August 2017
5 //
6 // Class to manipulate a string.
7 
8 #include <string>
9 #include <sstream>
10 #include <vector>
11 
12 #ifndef StringManipulator_H
13 #define StringManipulator_H
14 
16 
17 public:
18 
19  using Index = unsigned int;
20  using StringVector = std::vector<std::string>;
21 
22  // Fetch a fill value for an output stream as follows:
23  // '0' - zero or positive integers
24  // '-' - negative integers
25  template<typename T>
26  static char
27  getFill(typename std::enable_if<std::is_integral<T>::value, const T&>::type val) {
28  return val < 0 ? '-' : '0';
29  }
30  // '_' - otherwise
31  template<typename T>
32  static char
33  getFill(typename std::enable_if<!std::is_integral<T>::value, const T&>::type val) {
34  return '_';
35  }
36 
37  // Convert a float to string.
38  // val - input float
39  // prec - precision of the output: # digits after decimal point (dp)
40  // trunc - If true, trailing zeroes afterd dp and trailing dp are removed
41  // sdot - If not blank, dp is replaced with this string
42  // sdot - If not blank, minus sign is replaced with this string
43  static std::string
44  floatToString(float val, int prec, bool trunc, std::string sdot ="", std::string smin ="");
45 
46  // Ctor from a string.
47  // If copy is false, this object will modify the passed string.
48  // If true, the modified copy may be retrieved with str().
50  : m_str(copy ? m_strCopy : strin), m_strCopy(strin) { }
51 
52  // Ctor from a const string.
53  explicit StringManipulator(const std::string& sin) : m_str(m_strCopy), m_strCopy(sin) { }
54 
55  // Ctor from a C-string.
56  explicit StringManipulator(const char* chin) : m_str(m_strCopy), m_strCopy(chin) { }
57 
58  // Set/get log level.
60  Index logLevel() const { return m_LogLevel; }
61 
62  // Return the manipulated string.
63  const std::string& str() const { return m_str; }
64 
65  // Return the manipulated C string.
66  const char* c_str() const { return m_str.c_str(); }
67 
68  // Return the size of the string.
69  std::string::size_type size() const { return str().size(); }
70 
71  // Replace all occurences of a substring with a value.
72  // Returns the number of replacements (<0 for error).
73  template<typename T>
74  int replace(std::string substr, const T& xsub);
75 
76  // Replace all occurences of a substring with a value
77  // with fixed width.
78  // Returns the number of replacements (<0 for error).
79  template<typename T>
80  int replaceFixedWidth(std::string substr, const T& xsub, Index width);
81 
82  // Split a string into substrings bounded by the ends and by any of the
83  // Iff fullSplit is true, empty strings are included.
84  // E.g. for seps = "/,", "who,am//I?/" -->
85  // {"who", "am", "I?"} for fullSplit = false and
86  // {"who", "am", "", "I?", ""} for fullSplit = true
87  const std::vector<std::string>& split(std::string seps, bool fullSplit =false);
88 
89  // Return the strings obtained by iterating over parts in each split region.
90  // e.g. "R. {A,M}. Nixon" --> "R. A. Nixon", "R. M. Nixon".
91  // The >2 split pattern spat specifies the splitting:
92  // first char flags the start of a split region
93  // last char flags the end of a split region
94  // remaining chars are separators (seps in split(...)
96 
97  // Return the strings from the last split.
98  const StringVector& splits() const { return m_splits; }
99 
100  // Conversions to aritmentic types.
101  // These fail if the string is empty or has extra characters following.
102 
103  // Return if string only contains digits (ddd..., where d = 0, 1, ..., 9).
104  bool isDigits() const;
105 
106  // Return if the string is an unsigned int (ddd... or +ddd...).
107  bool isUnsignedInt() const;
108 
109  // Return if the string is a signed int (ddd..., +ddd... or -ddd...).
110  bool isInt() const;
111 
112  // Return if the string is a float.
113  bool isFloat() const;
114 
115  // Convert string to int. Return valbad if not int.
116  int toInt(int valbad =0) const;
117 
118  // Convert string to unsigned int. Return valbad if not unsigned int.
119  unsigned int toUnsignedInt(unsigned int valbad =0) const;
120 
121  // Convert string to float. Return valbad if not int.
122  float toFloat(float valbad =0) const;
123 
124 private:
125 
126  int m_LogLevel = 0;
130 
131 };
132 
133 //**********************************************************************
134 
135 template<typename T>
136 int StringManipulator::replace(std::string ssubout, const T& xsubin) {
137  std::string ssubin;
138  bool havesub = false;
139  std::string::size_type ipos = m_str.find(ssubout);
140  int count = 0;
141  while ( ipos != std::string::npos ) {
142  if ( ! havesub ) {
143  std::ostringstream sssubin;
144  sssubin << xsubin;
145  ssubin = sssubin.str();
146  }
147  std::string::size_type lout = ssubout.size();
148  m_str.replace(ipos, lout, ssubin);
149  ipos = m_str.find(ssubout, ipos+lout);
150  ++count;
151  }
152  return count;
153 }
154 
155 //**********************************************************************
156 
157 template<typename T>
159 replaceFixedWidth(std::string ssubout, const T& xsubin, Index width) {
160  std::string ssubin;
161  char cfill = getFill<T>(xsubin);
162  bool havesub = false;
163  std::string::size_type ipos = m_str.find(ssubout);
164  int count = 0;
165  while ( ipos != std::string::npos ) {
166  if ( ! havesub ) {
167  std::ostringstream sssubin;
168  sssubin.fill(cfill);
169  sssubin.width(width);
170  sssubin << xsubin;
171  ssubin = sssubin.str();
172  }
173  std::string::size_type lout = ssubout.size();
174  m_str.replace(ipos, lout, ssubin);
175  ipos = m_str.find(ssubout, ipos+lout);
176  ++count;
177  }
178  return count;
179 }
180 
181 //**********************************************************************
182 
183 #endif
const StringVector & patternSplit(std::string spat)
static std::string floatToString(float val, int prec, bool trunc, std::string sdot="", std::string smin="")
const std::vector< std::string > & split(std::string seps, bool fullSplit=false)
std::string string
Definition: nybbler.cc:12
Index logLevel() const
int replace(std::string substr, const T &xsub)
const std::string & str() const
std::string::size_type size() const
unsigned int toUnsignedInt(unsigned int valbad=0) const
const StringVector & splits() const
void setLogLevel(Index logLevel)
StringManipulator(const char *chin)
const char * c_str() const
static char getFill(typename std::enable_if< std::is_integral< T >::value, const T & >::type val)
int toInt(int valbad=0) const
int replaceFixedWidth(std::string substr, const T &xsub, Index width)
T copy(T const &v)
StringManipulator(const std::string &sin)
StringManipulator(std::string &strin, bool copy)
std::vector< std::string > StringVector
bool isUnsignedInt() const
static char getFill(typename std::enable_if<!std::is_integral< T >::value, const T & >::type val)
float toFloat(float valbad=0) const