Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_StrUtils.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #include "Teuchos_StrUtils.hpp"
11 #include "Teuchos_Assert.hpp"
12 
13 
14 namespace Teuchos {
15 
16 
17 Array<std::string> StrUtils::readFile(std::istream& is, char comment)
18 {
19  std::string line;
20  Array<std::string> rtn(0);
21 
22  while (readLine(is, line))
23  {
24  if (line.length() > 0) rtn.append(before(line, comment));
25  line="";
26  }
27 
28  return rtn;
29 }
30 
31 
33 {
34  int begin = 0;
36  const size_t len = input.length();
37  for (size_t p=0; p<len; ++p) {
38  const bool isEnd = p==len-1;
39  if( input[p]=='\n' || input[p]=='\0' || input[p]=='\r' || isEnd )
40  {
41  if (p-begin > 1)
42  rtn.append(
43  subString( input, begin, p+(isEnd?(input[len-1]=='\n'?0:1):0) )
44  );
45  begin = p+1;
46  }
47  }
48  return rtn;
49 }
50 
51 
52 Array<Array<std::string> > StrUtils::tokenizeFile(std::istream& is, char comment)
53 {
54  std::string line;
55  Array<Array<std::string> > rtn(0);
56  Array<std::string> lines = readFile(is, comment);
57  rtn.reserve(lines.length());
58 
59  int count = 0;
60  for (int i=0; i<lines.length(); i++)
61  {
62  if (lines[i].length() == 0) continue;
63  Array<std::string> tokens = stringTokenizer(lines[i]);
64  if (tokens.length() == 0) continue;
65  rtn.append(tokens);
66  count++;
67  }
68 
69  return rtn;
70 }
71 
72 
73 bool StrUtils::readLine(std::istream& is, std::string& line)
74 {
75  char c[500];
76  if (line.length() > 0) line[0] = '\0';
77 
78  if (is.eof()) return false;
79  if (is.getline(c, 499))
80  {
81  line = std::string(c);
82  }
83 
84  return true;
85 }
86 
87 
89  Array<std::string> rtn(0);
90  unsigned int start = 0;
91 
92  while(start < str.length())
93  {
94  unsigned int wordStart = findNextNonWhitespace(str, start);
95  /* add any preceding whitespace */
96  if (wordStart > start)
97  {
98  rtn.append(subString(str, start, wordStart));
99  }
100  start = wordStart;
101  /* add the next word */
102  int stop = findNextWhitespace(str, start);
103  if (start-stop == 0) return rtn;
104  std::string sub = subString(str, start, stop);
105  rtn.append(sub);
106  start = stop;// findNextNonWhitespace(str, stop);
107  }
108  return rtn;
109 }
110 
111 
113  Array<std::string> rtn(0);
114  unsigned int start = 0;
115 
116  while(start < str.length())
117  {
118  start = findNextNonWhitespace(str, start);
119  int stop = findNextWhitespace(str, start);
120  if (start-stop == 0) return rtn;
121  std::string sub = subString(str, start, stop);
122  rtn.append(sub);
123  start = findNextNonWhitespace(str, stop);
124  }
125  return rtn;
126 }
127 
128 
130  int iStart)
131 {
132  std::string rtn;
133 
134  for (int i=iStart; i<tokens.length(); i++)
135  {
136  rtn += tokens[i];
137  if (i < (tokens.length()-1)) rtn += " ";
138  }
139  return rtn;
140 }
141 
142 
143 void StrUtils::splitList(const std::string& big, Array<std::string>& list)
144 {
145  if (subString(big, 0,1)!="[")
146  {
147  list.resize(1);
148  list[0] = big;
149  return;
150  }
151 
152  int parenDepth = 0;
153  int localCount = 0;
154  std::string tmp(big);
155  list.resize(0);
156 
157  // start at 1 to ignore '[';
158 
159  for (unsigned int i=1; i<big.length(); i++)
160  {
161  if (big[i]=='(') parenDepth++;
162  if (big[i]==')') parenDepth--;
163  if (big[i]==']')
164  {
165  tmp[localCount]='\0';
166  list.append(tmp);
167  break;
168  }
169  if (big[i]==',' && parenDepth==0)
170  {
171  tmp[localCount]='\0';
172  list.append(tmp);
173  tmp = big;
174  localCount = 0;
175  continue;
176  }
177  tmp[localCount] = big[i];
178  localCount++;
179  }
180 }
181 
182 
183 // return the position of the next whitespace in a std::string.
184 // If no whitespace, return -1;
185 
186 int StrUtils::findNextWhitespace(const std::string& str, int offset)
187 {
188  for (unsigned int i=0; i<(str.length()-offset); i++)
189  {
190  if (str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n')
191  {
192  return i+offset;
193  }
194  }
195  return static_cast<int>(str.length());
196 }
197 
198 
199 int StrUtils::findNextNonWhitespace(const std::string& str, int offset)
200 {
201  for (unsigned int i=0; i<(str.length()-offset); i++)
202  {
203  if (!(str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n'))
204  {
205  return i+offset;
206  }
207  }
208  return static_cast<int>(str.length());
209 }
210 
211 
212 std::string StrUtils::varTableSubstitute(const std::string& rawLine,
213  const Array<std::string>& varNames,
214  const Array<std::string>& varValues)
215 {
216  TEUCHOS_TEST_FOR_EXCEPTION(varNames.length() != varValues.length(),
217  std::runtime_error,
218  "mismatched variable tables in varTableSubstitute");
219 
220  std::string line = rawLine;
221  for (int i=0; i<varNames.length(); i++)
222  {
223  line = varSubstitute(line, varNames[i], varValues[i]);
224  }
225  return line;
226 }
227 
228 
229 std::string StrUtils::varSubstitute(const std::string& rawLine,
230  const std::string& varName,
231  const std::string& varValue)
232 {
233  std::string line = rawLine;
234 
235  // iterate because there might be more than one occurrence on this line
236  while (find(line, varName) >= 0)
237  {
238  std::string b = before(line, varName);
239  std::string a = after(line, varName);
240  line = b + varValue + a;
241  }
242  return line;
243 }
244 
245 
246 std::string StrUtils::before(const std::string& str, char sub)
247 {
248  char c[2];
249  c[0] = sub;
250  c[1] = 0;
251  return before(str, c);
252 }
253 
254 
255 std::string StrUtils::before(const std::string& str, const std::string& sub)
256 {
257  TEUCHOS_TEST_FOR_EXCEPTION(sub.c_str()==0,
258  std::runtime_error, "String::before: arg is null pointer");
259 
260  char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str());
261  if (p==0) return str;
262  int subLen = static_cast<int>(p-str.c_str());
263  std::string rtn(str.c_str(), subLen);
264  return rtn;
265 }
266 
267 
268 std::string StrUtils::after(const std::string& str, const std::string& sub)
269 {
270  TEUCHOS_TEST_FOR_EXCEPTION(sub.c_str()==0,
271  std::runtime_error, "String::after: arg is null pointer");
272 
273  // find beginning of substring
274  char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str()) ;
275  // if substring not found, return empty std::string
276  if (p==0) return std::string();
277  // offset to end of substring
278  p+= std::strlen(sub.c_str());
279  return std::string(p);
280 }
281 
282 
283 int StrUtils::find(const std::string& str, const std::string& sub)
284 {
285  char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str());
286  if (p==0) return -1;
287  return static_cast<int>(p-str.c_str());
288 }
289 
290 
291 bool StrUtils::isWhite(const std::string& str)
292 {
293  for (unsigned int i=0; i<str.length(); i++)
294  {
295  unsigned char c = str[i];
296  if (c >= 33 && c <= 126)
297  {
298  return false;
299  }
300  }
301  return true;
302 }
303 
304 
305 std::string StrUtils::fixUnprintableCharacters(const std::string& str)
306 {
307  std::string rtn = str;
308  for (unsigned int i=0; i<rtn.length(); i++)
309  {
310  unsigned char c = rtn[i];
311  if (c < 33 || c > 126)
312  {
313  if (c != '\t' && c != '\n'&& c != '\r' && c != '\f' && c != ' ')
314  {
315  rtn[i] = ' ';
316  }
317  }
318  }
319  return rtn;
320 }
321 
322 
323 std::string StrUtils::between(const std::string& str, const std::string& begin,
324  const std::string& end, std::string& front,
325  std::string& back)
326 {
327  front = before(str, begin);
328  std::string middle = before(after(str, begin), end);
329  back = after(str, end);
330  return middle;
331 }
332 
333 
334 std::string StrUtils::subString(const std::string& str, int begin, int end)
335 {
336  return std::string(str.c_str()+begin, end-begin);
337 }
338 
339 
340 std::string StrUtils::readFromStream(std::istream& /* is */)
341 {
342  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
343  "StrUtils::readFromStream isn't implemented yet");
344 
345  // NOTE (mfh 15 Sep 2014): Most compilers have figured out that the
346  // return statement below is unreachable. Some older compilers
347  // might not realize this. That's why the return statement was put
348  // there, so that those compilers don't warn that this function
349  // doesn't return a value. If it's a choice between one warning and
350  // another, I would prefer the choice that produces less code and
351  // doesn't have unreachable code (which never gets tested).
352 
353  //return "";
354 }
355 
356 
357 std::string StrUtils::allCaps(const std::string& s)
358 {
359  std::string rtn = s;
360  for (unsigned int i=0; i<rtn.length(); i++)
361  {
362  rtn[i] = toupper(rtn[i]);
363  }
364  return rtn;
365 }
366 
367 
368 double StrUtils::atof(const std::string& s)
369 {
370  return std::atof(s.c_str());
371 }
372 
373 
374 int StrUtils::atoi(const std::string& s)
375 {
376  return std::atoi(s.c_str());
377 }
378 
379 
380 std::ostream& StrUtils::printLines(
381  std::ostream &os
382  ,const std::string &linePrefix
383  ,const std::string &lines
384  )
385 {
386  typedef Teuchos::Array<std::string> array_t;
387  array_t linesArray = splitIntoLines(lines);
388  for( int i = 0; i < static_cast<int>(linesArray.size()); ++i )
389  {
390  os << linePrefix << linesArray[i] << "\n";
391  }
392  return os;
393 }
394 
395 
396 std::string StrUtils::removeAllSpaces(std::string stringToClean)
397 {
398  std::string::size_type pos=0;
399  bool spacesLeft = true;
400 
401  while(spacesLeft){
402  pos = stringToClean.find(" ");
403  if(pos != string::npos){
404  stringToClean.erase(pos,1);
405  }
406  else{
407  spacesLeft = false;
408  }
409  }
410  return stringToClean;
411 }
412 
413 
414 } // namespace Teuchos
void reserve(size_type n)
static std::string removeAllSpaces(std::string stringToClean)
Removes all the spaces in a string.
Array< T > & append(const T &x)
Add a new entry at the end of the array.
static int findNextNonWhitespace(const std::string &str, int offset)
static std::string allCaps(const std::string &str)
Converts a std::string to all upper case.
static Array< Array< std::string > > tokenizeFile(std::istream &is, char comment)
Tokenize a file into whitespace-delimited tokens.
static std::string after(const std::string &str, const std::string &sub)
Find the substring after a specified substring. For example, before(&quot;abcdefghij&quot;, &quot;gh&quot;) returns &quot;ij&quot;...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
static Array< std::string > splitIntoLines(const std::string &input)
Split an input std::string that contains newlines into an array of strings, one for each line...
static std::ostream & printLines(std::ostream &os, const std::string &linePrefix, const std::string &lines)
Print lines with prefix first.
static bool readLine(std::istream &is, std::string &line)
Read a single line into a std::string.
static double atof(const std::string &str)
Returns the double value of a std::string.
A std::string utilities class for Teuchos.
static std::string between(const std::string &str, const std::string &begin, const std::string &end, std::string &front, std::string &back)
Returns the std::string between two delimiting strings, and returns by reference the strings before a...
static std::string varSubstitute(const std::string &rawLine, const std::string &varName, const std::string &varValue)
static std::string subString(const std::string &str, int begin, int end)
Returns the substring between two positions.
static std::string reassembleFromTokens(const Array< std::string > &tokens, int iStart=0)
static std::string before(const std::string &str, const std::string &sub)
Find the substring before a specified substring. For example, before(&quot;abcdefghij&quot;, &quot;gh&quot;) returns &quot;abcdef&quot;.
static std::string varTableSubstitute(const std::string &rawLine, const Array< std::string > &varNames, const Array< std::string > &varValues)
void resize(size_type new_size, const value_type &x=value_type())
static bool isWhite(const std::string &str)
Returns true if a std::string consists entirely of whitespace.
static std::string fixUnprintableCharacters(const std::string &str)
Convert unprintable non-null characters to whitespace.
int length() const
Return number of elements in the array.
static std::string readFromStream(std::istream &is)
static Array< std::string > stringTokenizer(const std::string &str)
static Array< std::string > readFile(std::istream &is, char comment)
Read a file, putting each line into a std::string.
static int atoi(const std::string &str)
Returns the int value of a std::string.
static Array< std::string > getTokensPlusWhitespace(const std::string &str)
static void splitList(const std::string &bigstring, Array< std::string > &elements)
static int findNextWhitespace(const std::string &str, int offset)
static int find(const std::string &str, const std::string &sub)
Find the position at which a substring first occurs. For example, find(&quot;abcdefghij&quot;, &quot;gh&quot;) returns 6.