Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_StrUtils.cpp
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  Array<std::string> StrUtils::splitString(const std::string_view s, const char sep) {
52  typedef std::string::size_type size_type;
54  size_type cur_pos, last_pos = 0, length = s.length();
55  while (last_pos < length + 1) {
56  cur_pos = s.find_first_of(sep, last_pos);
57  if (cur_pos == std::string::npos) {
58  cur_pos = length;
59  }
60  if (cur_pos != last_pos) {
61  auto token =
62  std::string(s.data() + last_pos, (size_type)cur_pos - last_pos);
63  rtn.append(token);
64  }
65  last_pos = cur_pos + 1;
66  }
67  return rtn;
68  }
69 
70 
71 Array<Array<std::string> > StrUtils::tokenizeFile(std::istream& is, char comment)
72 {
73  std::string line;
74  Array<Array<std::string> > rtn(0);
75  Array<std::string> lines = readFile(is, comment);
76  rtn.reserve(lines.length());
77 
78  int count = 0;
79  for (int i=0; i<lines.length(); i++)
80  {
81  if (lines[i].length() == 0) continue;
82  Array<std::string> tokens = stringTokenizer(lines[i]);
83  if (tokens.length() == 0) continue;
84  rtn.append(tokens);
85  count++;
86  }
87 
88  return rtn;
89 }
90 
91 
92 bool StrUtils::readLine(std::istream& is, std::string& line)
93 {
94  char c[500];
95  if (line.length() > 0) line[0] = '\0';
96 
97  if (is.eof()) return false;
98  if (is.getline(c, 499))
99  {
100  line = std::string(c);
101  }
102 
103  return true;
104 }
105 
106 
108  Array<std::string> rtn(0);
109  unsigned int start = 0;
110 
111  while(start < str.length())
112  {
113  unsigned int wordStart = findNextNonWhitespace(str, start);
114  /* add any preceding whitespace */
115  if (wordStart > start)
116  {
117  rtn.append(subString(str, start, wordStart));
118  }
119  start = wordStart;
120  /* add the next word */
121  int stop = findNextWhitespace(str, start);
122  if (start-stop == 0) return rtn;
123  std::string sub = subString(str, start, stop);
124  rtn.append(sub);
125  start = stop;// findNextNonWhitespace(str, stop);
126  }
127  return rtn;
128 }
129 
130 
132  Array<std::string> rtn(0);
133  unsigned int start = 0;
134 
135  while(start < str.length())
136  {
137  start = findNextNonWhitespace(str, start);
138  int stop = findNextWhitespace(str, start);
139  if (start-stop == 0) return rtn;
140  std::string sub = subString(str, start, stop);
141  rtn.append(sub);
142  start = findNextNonWhitespace(str, stop);
143  }
144  return rtn;
145 }
146 
147 
149  int iStart)
150 {
151  std::string rtn;
152 
153  for (int i=iStart; i<tokens.length(); i++)
154  {
155  rtn += tokens[i];
156  if (i < (tokens.length()-1)) rtn += " ";
157  }
158  return rtn;
159 }
160 
161 
162 void StrUtils::splitList(const std::string& big, Array<std::string>& list)
163 {
164  if (subString(big, 0,1)!="[")
165  {
166  list.resize(1);
167  list[0] = big;
168  return;
169  }
170 
171  int parenDepth = 0;
172  int localCount = 0;
173  std::string tmp(big);
174  list.resize(0);
175 
176  // start at 1 to ignore '[';
177 
178  for (unsigned int i=1; i<big.length(); i++)
179  {
180  if (big[i]=='(') parenDepth++;
181  if (big[i]==')') parenDepth--;
182  if (big[i]==']')
183  {
184  tmp[localCount]='\0';
185  list.append(tmp);
186  break;
187  }
188  if (big[i]==',' && parenDepth==0)
189  {
190  tmp[localCount]='\0';
191  list.append(tmp);
192  tmp = big;
193  localCount = 0;
194  continue;
195  }
196  tmp[localCount] = big[i];
197  localCount++;
198  }
199 }
200 
201 
202 // return the position of the next whitespace in a std::string.
203 // If no whitespace, return -1;
204 
205 int StrUtils::findNextWhitespace(const std::string& str, int offset)
206 {
207  for (unsigned int i=0; i<(str.length()-offset); i++)
208  {
209  if (str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n')
210  {
211  return i+offset;
212  }
213  }
214  return static_cast<int>(str.length());
215 }
216 
217 
218 int StrUtils::findNextNonWhitespace(const std::string& str, int offset)
219 {
220  for (unsigned int i=0; i<(str.length()-offset); i++)
221  {
222  if (!(str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n'))
223  {
224  return i+offset;
225  }
226  }
227  return static_cast<int>(str.length());
228 }
229 
230 
231 std::string StrUtils::varTableSubstitute(const std::string& rawLine,
232  const Array<std::string>& varNames,
233  const Array<std::string>& varValues)
234 {
235  TEUCHOS_TEST_FOR_EXCEPTION(varNames.length() != varValues.length(),
236  std::runtime_error,
237  "mismatched variable tables in varTableSubstitute");
238 
239  std::string line = rawLine;
240  for (int i=0; i<varNames.length(); i++)
241  {
242  line = varSubstitute(line, varNames[i], varValues[i]);
243  }
244  return line;
245 }
246 
247 
248 std::string StrUtils::varSubstitute(const std::string& rawLine,
249  const std::string& varName,
250  const std::string& varValue)
251 {
252  std::string line = rawLine;
253 
254  // iterate because there might be more than one occurrence on this line
255  while (find(line, varName) >= 0)
256  {
257  std::string b = before(line, varName);
258  std::string a = after(line, varName);
259  line = b + varValue + a;
260  }
261  return line;
262 }
263 
264 
265 std::string StrUtils::before(const std::string& str, char sub)
266 {
267  char c[2];
268  c[0] = sub;
269  c[1] = 0;
270  return before(str, c);
271 }
272 
273 
274 std::string StrUtils::before(const std::string& str, const std::string& sub)
275 {
276  TEUCHOS_TEST_FOR_EXCEPTION(sub.c_str()==0,
277  std::runtime_error, "String::before: arg is null pointer");
278 
279  char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str());
280  if (p==0) return str;
281  int subLen = static_cast<int>(p-str.c_str());
282  std::string rtn(str.c_str(), subLen);
283  return rtn;
284 }
285 
286 
287 std::string StrUtils::after(const std::string& str, const std::string& sub)
288 {
289  TEUCHOS_TEST_FOR_EXCEPTION(sub.c_str()==0,
290  std::runtime_error, "String::after: arg is null pointer");
291 
292  // find beginning of substring
293  char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str()) ;
294  // if substring not found, return empty std::string
295  if (p==0) return std::string();
296  // offset to end of substring
297  p+= std::strlen(sub.c_str());
298  return std::string(p);
299 }
300 
301 
302 int StrUtils::find(const std::string& str, const std::string& sub)
303 {
304  char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str());
305  if (p==0) return -1;
306  return static_cast<int>(p-str.c_str());
307 }
308 
309 
310 bool StrUtils::isWhite(const std::string& str)
311 {
312  for (unsigned int i=0; i<str.length(); i++)
313  {
314  unsigned char c = str[i];
315  if (c >= 33 && c <= 126)
316  {
317  return false;
318  }
319  }
320  return true;
321 }
322 
323 
324 std::string StrUtils::fixUnprintableCharacters(const std::string& str)
325 {
326  std::string rtn = str;
327  for (unsigned int i=0; i<rtn.length(); i++)
328  {
329  unsigned char c = rtn[i];
330  if (c < 33 || c > 126)
331  {
332  if (c != '\t' && c != '\n'&& c != '\r' && c != '\f' && c != ' ')
333  {
334  rtn[i] = ' ';
335  }
336  }
337  }
338  return rtn;
339 }
340 
341 
342 std::string StrUtils::between(const std::string& str, const std::string& begin,
343  const std::string& end, std::string& front,
344  std::string& back)
345 {
346  front = before(str, begin);
347  std::string middle = before(after(str, begin), end);
348  back = after(str, end);
349  return middle;
350 }
351 
352 
353 std::string StrUtils::subString(const std::string& str, int begin, int end)
354 {
355  return std::string(str.c_str()+begin, end-begin);
356 }
357 
358 
359 std::string StrUtils::readFromStream(std::istream& /* is */)
360 {
361  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
362  "StrUtils::readFromStream isn't implemented yet");
363 
364  // NOTE (mfh 15 Sep 2014): Most compilers have figured out that the
365  // return statement below is unreachable. Some older compilers
366  // might not realize this. That's why the return statement was put
367  // there, so that those compilers don't warn that this function
368  // doesn't return a value. If it's a choice between one warning and
369  // another, I would prefer the choice that produces less code and
370  // doesn't have unreachable code (which never gets tested).
371 
372  //return "";
373 }
374 
375 
376 std::string StrUtils::allCaps(const std::string& s)
377 {
378  std::string rtn = s;
379  for (unsigned int i=0; i<rtn.length(); i++)
380  {
381  rtn[i] = toupper(rtn[i]);
382  }
383  return rtn;
384 }
385 
386 
387 double StrUtils::atof(const std::string& s)
388 {
389  return std::atof(s.c_str());
390 }
391 
392 
393 int StrUtils::atoi(const std::string& s)
394 {
395  return std::atoi(s.c_str());
396 }
397 
398 
399 std::ostream& StrUtils::printLines(
400  std::ostream &os
401  ,const std::string &linePrefix
402  ,const std::string &lines
403  )
404 {
405  typedef Teuchos::Array<std::string> array_t;
406  array_t linesArray = splitIntoLines(lines);
407  for( int i = 0; i < static_cast<int>(linesArray.size()); ++i )
408  {
409  os << linePrefix << linesArray[i] << "\n";
410  }
411  return os;
412 }
413 
414 
415 std::string StrUtils::removeAllSpaces(std::string stringToClean)
416 {
417  std::string::size_type pos=0;
418  bool spacesLeft = true;
419 
420  while(spacesLeft){
421  pos = stringToClean.find(" ");
422  if(pos != string::npos){
423  stringToClean.erase(pos,1);
424  }
425  else{
426  spacesLeft = false;
427  }
428  }
429  return stringToClean;
430 }
431 
432 
433 } // 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 Array< std::string > splitString(const std::string_view s, const char sep= ',')
Split an input std::string using a seperator char sep.
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 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.