_string.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:7k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _string.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #include <LEDA/basic.h>
  12. #include <LEDA/string.h>
  13. #include <stdio.h>
  14. #include <stdarg.h>
  15. #include <string.h>
  16. #include <ctype.h>
  17. //------------------------------------------------------------------------------
  18. // String
  19. //------------------------------------------------------------------------------
  20. string_rep::string_rep(const char* p) 
  21. { s = string::str_dup(p); }
  22. string_rep::string_rep(const char* p, const char* q) 
  23. { s = string::str_cat(p,q); }
  24. string_rep::string_rep(char c)   
  25. { char p[2];
  26.   p[0] = c;
  27.   p[1] = '';
  28.   s=string::str_dup(p); 
  29.  }
  30. char* string::str_dup(const char* p)
  31. { if (p==nil) error_handler(1,"string::str_dup: nil argument");
  32.   char* q = new char[strlen(p)+1];
  33.   if (q==nil) error_handler(1,"string::str_dup: out of memory");
  34.   strcpy(q,p);
  35.   return q;
  36. }
  37. char* string::str_cat(const char* p1, const char* p2)
  38. { char* q = new char[strlen(p1)+strlen(p2)+1];
  39.   if (q==nil) error_handler(1,"string::str_cat: out of memory");
  40.   strcpy(q,p1);
  41.   strcat(q,p2);
  42.   return q;
  43.  }
  44. char* string::str_ncat(int argc, char** argv)
  45. { int l=0;
  46.   int i;
  47.   for(i=0;i<argc;i++)  l += (strlen(argv[i])+1); 
  48.   char* q = new char[l+1];
  49.   if (q==nil) error_handler(1,"string::str_cat: out of memory");
  50.   q[0] = 0;
  51.   for(i=0;i<argc;i++)
  52.   { strcat(q,argv[i]);
  53.     strcat(q," ");
  54.    }
  55.   return q;
  56.  }
  57. void string::read(istream& s, char delim)
  58. { char buf[512];
  59.   char* q = buf+511;
  60.   bool go = true;
  61.   operator=(""); // clear string
  62.   while (s && go)
  63.   { char* p;
  64.     for(p = buf; p < q && s.get(*p); p++)
  65.     { if (*p == delim) 
  66.       { if (delim != 'n') s.putback(*p);
  67.         go = false;
  68.         break;
  69.        }
  70.      } 
  71.     *p = '';
  72.     operator+=(buf);
  73.    }
  74. }
  75. #define STRING_CONSTRUCTOR(type)                         
  76. string::string(const char* f, type x, ...)               
  77. { char buf1[512];                                        
  78.   char buf2[512];                                        
  79.   char* q = buf1;                                        
  80.   int first = 1;                                         
  81.   /* copy f to buf1 doubling all %'s except the first */ 
  82.   while(*f != '')                                      
  83.     if ((*q++ = *f++) == '%')                            
  84.       if (!first) *q++ = '%';                            
  85.       else first = 0;                                    
  86.   *q = '';                                             
  87.   /* insert first argument x*/                           
  88.   sprintf(buf2,buf1,x);                                  
  89.   /* insert the rest */                                  
  90.   va_list arg_list;                                      
  91.   va_start(arg_list,x);                                  
  92.   vsprintf(buf1,buf2,arg_list);                          
  93.   PTR = new string_rep(buf1);                            
  94. }
  95.     
  96.   
  97. STRING_CONSTRUCTOR(char)
  98. STRING_CONSTRUCTOR(unsigned char)
  99. STRING_CONSTRUCTOR(short)
  100. STRING_CONSTRUCTOR(unsigned short)
  101. STRING_CONSTRUCTOR(int)
  102. STRING_CONSTRUCTOR(unsigned int)
  103. STRING_CONSTRUCTOR(long)
  104. STRING_CONSTRUCTOR(unsigned long)
  105. STRING_CONSTRUCTOR(float)
  106. STRING_CONSTRUCTOR(double)
  107. STRING_CONSTRUCTOR(void*)
  108. int string::length() const  { return strlen(cstring()); }
  109. char string::operator[](int i) const
  110. { if (i<0 || length() <= i) 
  111.     error_handler(1,"string[]: index out of range");
  112.   return ptr()->s[i];
  113. }
  114. char& string::operator[](int i)
  115. { if (i<0 || length() <= i) 
  116.     error_handler(1,"string[]: index out of range");
  117.   if (refs() > 1) *this = cstring();    // disconnect
  118.   return ptr()->s[i];
  119. }
  120. string& string::operator+=(const string& x) 
  121. { *this = *this + x; 
  122.   return *this; 
  123.  }
  124. //friends
  125. string  operator+(const string& x ,const string& y)
  126. { return new string_rep(x.cstring(),y.cstring()); }
  127. bool operator==(const string& x, const string& y) 
  128. { if (x.ptr() == y.ptr()) return true;
  129.   return strcmp(x.cstring(),y.cstring())==0; 
  130.  }
  131. bool operator==(const string& x, const char* y) 
  132. { return strcmp(x.cstring(),y)==0; }
  133. bool operator!=(const string& x, const string& y) 
  134. { if (x.ptr() == y.ptr()) return false;
  135.   return strcmp(x.cstring(),y.cstring())!=0; 
  136.  }
  137. bool operator!=(const string& x, const char* y) 
  138. { return strcmp(x.cstring(),y)!=0; }
  139. bool operator<(const string& x, const string& y)  
  140. { return strcmp(x.cstring(),y.cstring())<0; }
  141. bool operator>(const string& x, const string& y)  
  142. { return strcmp(x.cstring(),y.cstring())>0; }
  143. bool operator<=(const string& x, const string& y) 
  144. { if (x.ptr() == y.ptr()) return true;
  145.   return strcmp(x.cstring(),y.cstring())<=0; 
  146.  }
  147. bool operator>=(const string& x, const string& y) 
  148. { if (x.ptr() == y.ptr()) return true;
  149.   return strcmp(x.cstring(),y.cstring())>=0; 
  150.  }
  151. istream& operator>>(istream& in, string& x)
  152. { char buf[256];
  153.   char* p = buf;
  154.   //skip leading white space (but not eol if in = cin)
  155.   while (in.get(*p) && isspace(*p) && (&in != &cin || *p != 'n')); 
  156.   if (in && *p != 'n')
  157.   { p++;
  158.     while (in.get(*p) && !isspace(*p)) p++;
  159.    }
  160.   *p = '';
  161.   x.operator=(buf);
  162.   return in;
  163. }
  164. ostream& operator<<(ostream& out, const string& x) 
  165. { return out << x.cstring(); }
  166. string string::sub(int i, int j) const
  167. {
  168.   if (j >= length()) j = length() - 1;
  169.   if (i < 0) i = 0;
  170.   int l = j-i+1;
  171.   if (l <= 0)  return string("");
  172.   char* q = new char[l+1];
  173.   strncpy(q,cstring()+i,l);
  174.   q[l] = '';
  175.   string s(q);
  176.   delete[] q;
  177.   return s;
  178. }
  179. int string::pos(string s1, int i) const
  180. {
  181.   int l1 = s1.length();
  182.   if (l1==0 || i >= length()) return -1;
  183.   char c = s1[0];
  184.   char* q = cstring() + i;
  185.   while (*q)
  186.     { while ( (*q) && (*q != c) ) q++;
  187.       if ( strncmp(q,s1.cstring(),l1)==0 ) break ;
  188.       if (*q) q++;
  189.      }
  190.   return (*q) ? int((q - cstring())/ sizeof(char)) :  -1;
  191. }
  192. string string::insert(string s, int i) const
  193. { return sub(0,i-1) + s + sub(i,length()-1); }
  194. string string::insert(int i, string s) const
  195. { return sub(0,i-1) + s + sub(i,length()-1); }
  196. string string::del(int i, int j) const
  197. { return sub(0,i-1) + sub(j+1,length()-1); }
  198. string string::del(const string& s, int n) const
  199. { return replace(s,"",n); }
  200. string string::replace(int i, int j, const string& s) const
  201. { return sub(0,i-1) + s + sub(j+1,length()-1); }
  202. string string::replace(const string& s1, const string& s2, int n) const 
  203.   // replace n-th (all if n=0) occurrence of s1 by s2 
  204.   int i = 0;
  205.   int match = 0;  
  206.   int l1 = s1.length();
  207.   string tmp;
  208.   for(;;)
  209.   { int j = pos(s1,i);
  210.     if (j < 0 ) break;
  211.     tmp += sub(i,j-1);
  212.     if (n==0 || ++match == n)
  213.        tmp += s2;
  214.     else
  215.        tmp += s1;
  216.     i = j+l1;
  217.    }
  218.   tmp += sub(i,length()-1);
  219.   return tmp;
  220.  }
  221. string string::format(string f) const
  222.   char buf[512];
  223.   sprintf(buf,~f,cstring());
  224.   return buf;
  225.  }
  226. int string::cmp(const string& x, const string& y) { return strcmp(x,y); }