Mass++ Common Libraries v2.7.5
 All Classes Namespaces Files Functions Variables Enumerations Macros
StringFunctions.cpp
Go to the documentation of this file.
1 
12 #include "stdafx.h"
13 
14 #include "StringFunctions.h"
15 #include "CoreMacros.h"
16 
17 #include <stdio.h>
18 #include <stdarg.h>
19 #include <stdlib.h>
20 #include <set>
21 #include <list>
22 #include <boost/regex.hpp>
23 
24 
25 #define TMP_STRING "MaSs2pLus0PlUs1tMp1sTrInG"
26 
27 
28 // define
29 #ifdef _MSC_VER
30 #define STRING_BUFFER_SIZE 0x1000
31 #endif // _MSC_VER
32 
33 
35 const char* g_whiteSpaces = " \t\r\n";
36 
38 std::set<char> g_whiteSpacesSet;
39 
40 
41 // get formated string
42 std::string strfmt( const char* fmt, ... ) {
43  // definition
44  char* s = NULL;
45  va_list ap;
46 
47  // get string
48  va_start( ap, fmt );
49 
50 #ifdef _MSC_VER
51 
52  s = (char*)malloc( STRING_BUFFER_SIZE );
53  vsprintf_s( s, STRING_BUFFER_SIZE, fmt, ap );
54 
55 #else
56 
57  vasprintf( &s, fmt, ap );
58 
59 #endif // _MSC_VER
60 
61  va_end( ap );
62 
63  // create std::string object
64  std::string s2 = std::string( s );
65 
66  // free
67  free( s );
68 
69  return s2;
70 }
71 
72 // wstring -> string
73 std::string wstr2str( std::wstring& ws ) {
74  // get buffer size
75  size_t bufferSize = ( ws.length() + 1 ) * MB_CUR_MAX;
76 
77  // create buffer
78  char* buffer = new char[ bufferSize ];
79 
80  // convert
81  size_t size = 0;
82 
83 #ifdef _MSC_VER
84  wcstombs_s( &size, buffer, bufferSize, ws.c_str(), ws.size() );
85 #else
86  size = wcstombs( buffer, ws.c_str(), size );
87 #endif // _MSC_VER
88 
89  std::string s = std::string( buffer );
90 
91  delete[] buffer;
92 
93  return s;
94 }
95 
96 // string -> wstring
97 std::wstring str2wstr( std::string& s ) {
98  // get buffer size
99  size_t bufferSize = s.length() + 1;
100 
101  // create buffer
102  wchar_t* buffer = new wchar_t[ bufferSize ];
103 
104  // convert
105  size_t size = 0;
106 
107 #ifdef _MSC_VER
108  mbstowcs_s( &size, buffer, bufferSize, s.c_str(), s.size() );
109 #else
110  size = mbstowcs( buffer, s.c_str(), bufferSize );
111 #endif // _MSC_VER
112 
113  std::wstring ws = std::wstring( buffer );
114 
115  delete[] buffer;
116 
117  return ws;
118 }
119 
120 // to lower case
121 std::string tolowercase( const char* s ) {
122  // string object
123  std::string str;
124  if( s == NULL ) {
125  return str;
126  }
127 
128  // length
129  unsigned int len = (unsigned int)strlen( s );
130 
131  // to lower case
132  for( unsigned int i = 0; i < len; i++ ) {
133  str.push_back( tolower( s[ i ] ) );
134  }
135 
136  return str;
137 }
138 
139 // to upper case
140 std::string touppercase( const char* s ) {
141  // string object
142  std::string str;
143  if( s == NULL ) {
144  return str;
145  }
146 
147  // length
148  unsigned int len = (unsigned int)strlen( s );
149 
150  // to upper case
151  for( unsigned int i = 0; i < len; i++ ) {
152  str.push_back( toupper( s[ i ] ) );
153  }
154 
155  return str;
156 }
157 
158 // compare ignore case
159 int compareignorecase( const char* s1, const char* s2 ) {
160  return strcmp( tolowercase( s1 ).c_str(), tolowercase( s2 ).c_str() );
161 }
162 
163 // get tokens
164 unsigned int stringtoken(
165  const char* s,
166  const char* delim,
167  std::vector< std::string >& tokens
168 ){
169  // check
170  std::string::size_type delimLen = strlen( delim );
171  if( delimLen == 0 ) {
172  tokens.push_back( s );
173  return 1;
174  }
175 
176  // string
177  std::string str = NVL( s, "" );
178  std::list< std::string > strList;
179 
180  // double quote
181  std::string::size_type start = std::string::npos;
182  std::string::size_type pos = 0;
183  while( ( pos = str.find( "\"", ( start == std::string::npos ? 0 : start + 1 ) ) ) != str.npos ) {
184  if( start == std::string::npos ) {
185  start = pos;
186  }
187  else {
188  strList.push_back( str.substr( start + 1, pos - start - 1 ) );
189 
190  std::string tmp = str.substr( 0, start );
191  tmp.append( TMP_STRING );
192  tmp.append( str.substr( pos + 1 ) );
193  str = tmp;
194 
195  start = std::string::npos;
196  }
197  }
198  str = FMT( "%s%c", str.c_str(), delim[ 0 ] );
199 
200  // separate
201  std::string::size_type tmpLen = strlen( TMP_STRING );
202  std::string::size_type cnt = 0;
203  start = 0;
204 
205  for( unsigned int i = 0; i < str.length(); i++ ) {
206  // check the character
207  char c = str[ i ];
208  bool found = false;
209  for( unsigned int j = 0; j < delimLen && !found; j++ ) {
210  if( c == delim[ j ] ) {
211  found = true;
212  }
213  }
214 
215  // add
216  if( found ) {
217  std::string val = str.substr( start, i - start );
218 
219  std::string::size_type rPos = 0;
220  while( ( rPos = val.find( TMP_STRING ) ) != val.npos ) {
221  std::string tmp = val.substr( 0, rPos );
222  tmp.append( strList.front() );
223  strList.pop_front();
224  tmp.append( val.substr( rPos + tmpLen ) );
225 
226  val = tmp;
227  }
228 
229  if( !val.empty() ) {
230  tokens.push_back( val );
231  cnt++;
232  }
233 
234  start = i + 1;
235  }
236  }
237 
238  return (unsigned int)cnt;
239 }
240 
241 // string separate
242 unsigned int stringseparate(
243  const char* s,
244  const char* separator,
245  std::vector< std::string >& tokens
246 ) {
247  // check
248  std::string::size_type sepLen = strlen( separator );
249  if( sepLen == 0 ) {
250  tokens.push_back( s );
251  return 1;
252  }
253 
254  // string
255  std::string str = NVL( s, "" );
256  std::list< std::string > strList;
257 
258  // double quote
259  std::string::size_type start = std::string::npos;
260  std::string::size_type pos = 0;
261  while( ( pos = str.find( "\"", ( start == std::string::npos ? 0 : start + 1 ) ) ) != str.npos ) {
262  if( start == std::string::npos ) {
263  start = pos;
264  }
265  else {
266  strList.push_back( str.substr( start + 1, (int)pos - start - 1 ) );
267 
268  std::string tmp = str.substr( 0, start );
269  tmp.append( TMP_STRING );
270  tmp.append( str.substr( pos + 1 ) );
271  str = tmp;
272 
273  start = std::string::npos;
274  }
275  }
276  str.append( separator );
277 
278  // separate
279  std::string::size_type tmpLen = strlen( TMP_STRING );
280  std::string::size_type cnt = 0;
281  start = 0;
282  pos = 0;
283 
284  while( ( pos = str.find( separator, start ) ) != str.npos ) {
285  // value
286  std::string val = str.substr( start, (int)pos - start );
287 
288  std::string::size_type rPos = 0;
289  while( ( rPos = val.find( TMP_STRING ) ) != val.npos ) {
290  std::string tmp = val.substr( 0, rPos );
291  tmp.append( strList.front() );
292  strList.pop_front();
293  tmp.append( val.substr( rPos + tmpLen ) );
294 
295  val = tmp;
296  }
297 
298  tokens.push_back( val );
299  cnt++;
300 
301  start = (int)( pos + sepLen );
302  }
303 
304  return (unsigned int)cnt;
305 }
306 
307 // integer number or not
308 bool isint( const char* s, const int radix, int* val ) {
309  // check parameter
310  if( s == NULL ) {
311  return false;
312  }
313 
314  // convert
315  char* endptr = NULL;
316  int v = strtol( s, &endptr, radix );
317 
318  if( endptr == s ) { // not integer
319  return false;
320  }
321 
322  // 変換できなかった文字から後の長さを調べる // SPEC 90640
323  if( 0 < strlen( endptr ) ){
324  // INTではないとみなす
325  return false;
326  }
327 
328  // store value.
329  if( val != NULL ) {
330  *val = v;
331  }
332  return true;
333 }
334 
335 // string -> int
336 int toint( const char* s, const int radix, const int dfval ) {
337  // check parameter
338  if( s == NULL ) {
339  return dfval;
340  }
341 
342  // convert
343  char* endptr = NULL;
344  int val = strtol( s, &endptr, radix );
345 
346  if( endptr == s ) { // character string doesn't show integer number.
347  val = dfval;
348  }
349 
350  return val;
351 }
352 
353 // integer number or not
354 bool isint64( const char* s, const int radix, long long* val ) {
355  // check parameter
356  if( s == NULL ) {
357  return false;
358  }
359 
360  // convert
361  char* endptr = NULL;
362  long long v = 0;
363 
364 #ifdef _MSC_VER
365  v = _strtoi64( s, &endptr, radix );
366 #else
367  v = strtoll( s, &endptr, radix );
368 #endif // _MSC_VER
369 
370  if( endptr == s ) { // not integer
371  return false;
372  }
373 
374  // store value.
375  if( val != NULL ) {
376  *val = v;
377  }
378  return true;
379 }
380 
381 // string -> int
382 long long toint64( const char* s, const int radix, const long long dfval ) {
383  // check parameter
384  if( s == NULL ) {
385  return dfval;
386  }
387 
388  // convert
389  char* endptr = NULL;
390  long long val = dfval;
391 
392 #ifdef _MSC_VER
393  val = _strtoi64( s, &endptr, radix );
394 #else
395  val = strtoll( s, &endptr, radix );
396 #endif // _MSC_VER
397 
398  if( endptr == s ) { // character string doesn't show integer number.
399  val = dfval;
400  }
401 
402  return val;
403 }
404 
405 // real number of not
406 bool isdouble( const char* s, double* val ) {
407  // check parameter
408  if( s == NULL ) {
409  return false;
410  }
411 
412  // convert
413  char* endptr = NULL;
414  double v = strtod( s, &endptr );
415  if( endptr == s ) { // not real number
416  return false;
417  }
418 
419  // 変換できなかった文字から後の長さを調べる // SPEC 90640
420  if( 0 < strlen( endptr ) ){
421  // doubleではないとみなす
422  return false;
423  }
424 
425  // store value.
426  if( val != NULL ) {
427  *val = v;
428  }
429  return true;
430 }
431 
432 // string -> double
433 double todouble( const char* s, const double dfval ) {
434  // check parameter
435  if( s == NULL ) {
436  return dfval;
437  }
438 
439  // convert
440  char* endptr = NULL;
441  double val = strtod( s, &endptr );
442  if( endptr == s ) { // character string doesn't sho real number.
443  val = dfval;
444  }
445 
446  return val;
447 }
448 
449 // get boolean value
450 bool tobool( const char* s, bool dfVal ) {
451  // convert to upper case
452  std::string value = touppercase( s );
453 
454  // get value
455  if( value.compare( "1" ) == 0
456  || value.compare( "TRUE" ) == 0 || value.compare( "ON" ) == 0 ) {
457  return true;
458  }
459  if( value.compare( "0" ) == 0
460  || value.compare( "FALSE" ) == 0 || value.compare( "OFF" ) == 0 ) {
461  return false;
462  }
463  return dfVal;
464 }
465 
466 // trim string
467 std::string trimstring( const char* s ) {
468  // string object
469  std::string str;
470 
471  // check parameter
472  if( s == NULL ) {
473  return str;
474  }
475 
476  // create white spaces set
477  if( g_whiteSpacesSet.size() == 0 ) {
478  size_t num = strlen( g_whiteSpaces );
479  for( unsigned int i = 0; i < num; i++ ) {
480  g_whiteSpacesSet.insert( g_whiteSpaces[i] );
481  }
482  }
483 
484  // create working buffer
485  size_t length = strlen( s );
486  size_t size = length + 1;
487  char* buffer = new char[ size ];
488 
489  // copy character string to buffer
490  memcpy( buffer, s, size );
491 
492  // trim the front end of string
493  char* firstChar = buffer;
494  while( g_whiteSpacesSet.find( *firstChar ) != g_whiteSpacesSet.end()
495  && *firstChar != '\0' ) {
496  firstChar++;
497  }
498 
499  // trim the back end of string
500  char* lastChar = buffer + length;
501  if( firstChar != lastChar ) {
502  lastChar--;
503  }
504  while( lastChar != firstChar
505  && g_whiteSpacesSet.find( *lastChar ) != g_whiteSpacesSet.end() ) {
506  *lastChar = '\0';
507  lastChar--;
508  }
509 
510  // create string object
511  std::string trimmed( firstChar );
512 
513  // double quote
514  if( trimmed.length() >= 2 && trimmed.front() == '\"' && trimmed.back() == '\"' ) {
515  trimmed = trimmed.substr( 1, trimmed.length() - 2 );
516  }
517 
518  delete[] buffer;
519 
520  return trimmed;
521 }
522 
523 // starts with
524 bool startswith( const char* s, const char* prefix ) {
525  // create string object
526  std::string str( NVL( s, "" ) );
527  std::string prfx( NVL( prefix, "" ) );
528 
529  // check
530  std::string::size_type pos = str.find( prfx );
531 
532  return ( pos == 0 );
533 }
534 
535 // ends with
536 bool endswith( const char* s, const char* suffix ) {
537  // create string object
538  std::string str( NVL( s, "" ) );
539  std::string sffx( NVL( suffix, "" ) );
540 
541  // check
542  size_t pos = str.rfind( sffx );
543 
544  return ( pos == ( str.length() - sffx.length() ) );
545 }
546 
547 // replace string
548 std::string replacestring( const char* s, const char* oldStr, const char* newStr ) {
549  // create string object
550  std::string str;
551  if( s == NULL ) {
552  return str;
553  }
554  str = s;
555 
556  // check parameters
557  if( oldStr == NULL || newStr == NULL ) {
558  return str;
559  }
560  if( strcmp( oldStr, newStr ) == 0 ) {
561  return str;
562  }
563 
564  // find substring
565  std::string::size_type pos = str.find( oldStr );
566  if( pos == str.npos ) {
567  return str;
568  }
569 
570  // replace
571  size_t length = strlen( oldStr );
572  str = str.substr( 0, pos ) + std::string( newStr ) + replacestring( s + ( pos + length), oldStr, newStr );
573 
574  return str;
575 }
576 
577 // shorten string
578 std::string shortenstring( const char* s, const unsigned int len, const bool cutTail ) {
579  // string object
580  std::string tmp = NVL( s, "" );
581 
582  // check the length
583  if( tmp.length() <= len ) {
584  return tmp;
585  }
586 
587  if( len <= 3 ) {
588  tmp = "...";
589  return tmp;
590  }
591 
592  // shorten
593  if( cutTail ) {
594  tmp = tmp.substr( 0, len - 3 );
595  tmp.append( "..." );
596  }
597  else {
598  tmp = tmp.substr( 3 );
599  tmp = FMT( "...%s", tmp.c_str() );
600  }
601 
602  return tmp;
603 }
604 
605 // regex search
606 std::string regexsearch( const char* s, const char* regex ) {
607  // return value
608  std::string ret;
609 
610  boost::regex r( regex );
611  boost::match_results< const char* > results;
612  if( boost::regex_search( s, results, r ) ) {
613  ret = results.str( 1 );
614  }
615 
616  return ret;
617 }
std::string strfmt(const char *fmt,...)
get formated string
std::string shortenstring(const char *s, const unsigned int len, const bool cutTail)
shorten the specified string
const char * g_whiteSpaces
white spaces
bool isdouble(const char *s, double *val)
judge whether sutisfied character string shows real number.
unsigned int stringseparate(const char *s, const char *separator, std::vector< std::string > &tokens)
separates string
basic macro collection
bool tobool(const char *s, bool dfVal)
get true or false from character string.
int toint(const char *s, const int radix, const int dfval)
convert string into integer
int compareignorecase(const char *s1, const char *s2)
compare two strings ignoring case considerations
std::string trimstring(const char *s)
remove white spaces from both ends of specified string
unsigned int stringtoken(const char *s, const char *delim, std::vector< std::string > &tokens)
get tokens from string
bool isint(const char *s, const int radix, int *val)
judge whether sutisfied character string shows integer number.
std::set< char > g_whiteSpacesSet
white spaces set
#define NVL(checkVal, replaceVal)
Definition: CoreMacros.h:99
#define NULL
Definition: CoreMacros.h:18
std::string tolowercase(const char *s)
convert all of the characters in the string given to lower case
bool isint64(const char *s, const int radix, long long *val)
judge whether sutisfied character string shows 64 bit integer number.
std::wstring str2wstr(std::string &s)
convert string to wstring
interfaces of string function
std::string replacestring(const char *s, const char *oldStr, const char *newStr)
replaces specified substring with another one
double todouble(const char *s, const double dfval)
convert string into double
std::string regexsearch(const char *s, const char *regex)
search string using regular expression.
std::string wstr2str(std::wstring &ws)
convert wstring to string
bool endswith(const char *s, const char *suffix)
judge whether there is a sub-string at the end of string
long long toint64(const char *s, const int radix, const long long dfval)
convert string into 64 bit integer
bool startswith(const char *s, const char *prefix)
judges whether there is a sub-string at the start of string
std::string touppercase(const char *s)
convert all of the characters int the string given to upper case