📄 dstring.cpp
字号:
} const int from_length = strlen(set_from); // create a String with a guaranteed reference count of 1 String tmpstr(*this); tmpstr.single_copy(); // Is there room? If not, pad. // Why -1? Imagine a String length 1, set position 1 to 'a'; // don't want it to be 2 bytes long, do we? if(startpos+from_length-1 > oldlen) tmpstr.pad_to_length(startpos+from_length-1, filler); // and set - can't use strcpy, don't want the null at the end char *cp1 = tmpstr.sdp->data+startpos-1; copystr(cp1, set_from); // and swap our sdp with tmpstr - the delete is done when tmpstr // is zapped String_data *tmpsdp = sdp; sdp = tmpstr.sdp; tmpstr.sdp = tmpsdp;}// Pad the String to length with the designated character// This used to be coded for compactness - the new version is for speed/*void String::pad_to_length(size_t length, char filler){ const size_t oldlen = nchars(); const size_t lendiff = length-oldlen; if(oldlen < length){ char *ncp = new char[lendiff+1]; memset(ncp, filler, lendiff); ncp[lendiff] = 0; operator +=(ncp); delete [] ncp; }}*/void String::pad_to_length(size_t length, char filler){ const size_t oldlen = nchars(); const size_t lendiff = length-oldlen; if(oldlen < length){ String_data *nsdp = newsdp(length+1); memcpy(nsdp->data, sdp->data, length+1); --*sdp; sdp = nsdp; memset(nsdp->data+oldlen, filler, lendiff); nsdp->data[length] = 0; }}void String::cvt_toupper(){ // assume that it will make a change, but don't copy own data // unnecessarily ... single_copy(); char c; for(char *ccp = sdp->data; (c = *ccp) != 0; ccp++){ if(isascii(c) && islower(c)) *ccp = toupper(c); }}void String::cvt_tolower(){ // assume that it will make a change, but don't copy own data // unnecessarily ... single_copy(); char c; for(char *ccp = sdp->data; (c = *ccp) != 0; ccp++){ if(isascii(c) && isupper(c)) *ccp = tolower(c); }}unsigned long String::ulongval()const{ return ulongval(10);}unsigned long String::ulongval(int base)const{ char *cp = 0; return strtoul(sdp->data, &cp, base);}double String::doubleval()const{ return strtod(sdp->data, 0);}void String::sprintf(const char *fmt, ...){ // char *msgbuf = new char[512]; // if(msgbuf == 0) // return; char msgbuf[512]; //msgbuf[511] = 0xff; va_list vl; va_start(vl, fmt); vsprintf(msgbuf, fmt, vl); va_end(vl); //if(msgbuf[511] != (char)0xff){ // const char *cp = "Aaargh - sprintf overflow\n"; //} // Yes, this could be made more efficient, but I prefer small code! operator =(msgbuf); // delete [] msgbuf;}// Case-insensitive comparisons. Return true for equal, false otherwiseint caseicmp(const char *cp1, const char *cp2){ for(;;){ char c1 = *cp1++, c2 = *cp2++; if(c1 == c2){ if(c1 == 0) return 1; else continue; } // Not equal if(tolower(c1) == tolower(c2)) continue; return 0; }}int caseicmp(const char *cp1, const String &sr){ return caseicmp(cp1, sr.cstring());}int caseicmp(const String &sr1, const String &sr2){ return caseicmp(sr1.cstring(), sr2.cstring());}int caseicmp(const String &sr, const char *cp){ return caseicmp(sr.cstring(), cp);}array_of_String::array_of_String(){}//array_of_String::array_of_String(const array_of_String& csr){// // implementation = new generic_ptr_array;// for(int i = 0; i < csr.element_count(); i++)// operator +=(csr[i]);//}//array_of_String::~array_of_String(){// // empty(); // delete (generic_ptr_array *)implementation;//}// void array_of_String::delete_last_element(){// generic_ptr_array *gp = (generic_ptr_array *)implementation;// delete (String *)(gp->last());// gp->delete_last_element();// }// int array_of_String::element_count()const{// return ((generic_ptr_array *)implementation)->element_count();// }// void array_of_String::insert_before_element(int index, const String &r){// generic_ptr_array *gp = (generic_ptr_array *)implementation;// gp->insert_before_element(index, new String(r));// }// void array_of_String::operator+=(const String &r){// generic_ptr_array *gp = (generic_ptr_array *)implementation;// gp->operator +=(new String(r));// }// void array_of_String::push(const String &r){// generic_ptr_array *gp = (generic_ptr_array *)implementation;// gp->push(new String(r));// }// String array_of_String::last_element()const{// generic_ptr_array *gp = (generic_ptr_array *)implementation;// return *(String *)(gp->last());// }// String array_of_String::pop(){// generic_ptr_array *gp = (generic_ptr_array *)implementation;// String *sp = (String *)(gp->pop());// String rv = *sp;// delete sp;// return rv;// }// void array_of_String::delete_this_element(int index){// generic_ptr_array *gp = (generic_ptr_array *)implementation;// delete (String *)(gp->operator[](index));// gp->delete_this_element(index);// }String & array_of_String::operator [](int i){// generic_ptr_array *gp = (generic_ptr_array *)implementation;// String *s = (String *)(gp->operator[](i));// if(s)// return *s; if(i >= 0 && i < element_count()) return list_of<String>::operator[](i); static String oops; oops = ""; return oops;}String array_of_String::extract(){ String rval = operator[](0); delete_this_element(0); return rval;}const String& array_of_String::operator[](int i)const{ return ((array_of_String *)this)->operator[](i);}// Take the String and break it into fields, appending them to the designated// array. The fields are separated by characters in the "delims" argument,// else whitespace. This is used extensively in the uucp code and seems to// work, but the logic of everything to do with delimiter checking has not// been formally tested on anything other than whitespace. Improvements would// perhaps be to allow a flag to specify whether consecutive delimiters indicate// empty fields or not... now done, see "strict"static int getargs(const String&csr, array_of_String &sar, const char *delims, int strict);static int getargs(const String &csr, array_of_String &sar);// Take a line of text. Split it into fields, where white space is the// separatorint getargs(const String &csr, array_of_String &sar){ return getargs(csr, sar, " \t\n", 0);}int array_of_String::getfields(const String &csr){ return ::getargs(csr, *this);}int array_of_String::getfields(const String &csr, const char *delims){ return ::getargs(csr, *this, delims, 0);}int array_of_String::strictgetfields(const String &csr, const char *delims){ return ::getargs(csr, *this, delims, 1);}// Strict means that *each* delimiter indicates a fieldint getargs(const String&csr, array_of_String &sar, const char *delims, int strict) { const char *line = csr.cstring(); int i = 0; sar.clear(); while (*line != '\0') { // skip leading delimiters ... if (strchr(delims, *line)){ if(strict) sar += ""; line++; }else { // got a non-delim character; record it String thisfield = line; const char *start = line; i++; char cdelim; while((cdelim = *line) != 0 && !strchr(delims, cdelim) ) line++; // at just off end now thisfield = thisfield.substr(1, int(line-start)); sar += thisfield; // And move past the delimiter if(cdelim) line++; } } return i;}int array_of_String::findat(const char * csr, findcase f){ return findat(String(csr), f);}int array_of_String::findat(const String &csr, findcase f){ String search = csr; if(f == ignorecase){ search.cvt_tolower(); } for(int i = 0; i < element_count(); i++){ String cmp = operator[](i); if(f == ignorecase){ cmp.cvt_tolower(); } if(search == cmp) return i; } return -1;}/*void array_of_String::operator =(const array_of_String &rhs){ if(this == &rhs) return; clear(); for(int i = 0; i < rhs.element_count(); i++){ *this += rhs[i]; }}*//*void array_of_String::sort(direction d){ // generic_ptr_array *gp = (generic_ptr_array *)implementation; list_of<String> &lor = *this; // A simple bubble sort is used - anything else is unlikely // to be a lot better const int upperbound = lor.element_count(); for(int i = 0; i < upperbound-1; i++){ for(int j = i+1; j < upperbound; j++){ void *&v1 = (lor.element_ref(i)); void *&v2 = (lor.element_ref(j)); if((*(String*)v1 > *(String *)v2) == (d == up)){ // swap them void *tv = v1; v1 = v2; v2 = tv; } } }}*/#ifdef MAIN#include <iostream.h>main(){ String s = "hello"; cout << s.cstring() << '\n'; s.pad_to_length(15, '*'); cout << s.cstring() << '\n'; s.set_substr(5, "12345"); cout << s.cstring() << '\n'; s.set_substr(10, "abcdefghijklm"); cout << s.cstring() << '\n'; s = ""; cout << "nchars " << s.nchars() << '\n'; //s.pad_to_length(10); //cout << "nchars " << s.nchars() << '\n'; s.set_substr(10, "abcdefghijklm"); cout << "nchars " << s.nchars() << '\n'; cout << s.cstring() << '\n'; cout << "now toupper and back\n"; s.cvt_toupper(); cout << s.cstring() << '\n'; s.cvt_tolower(); cout << s.cstring() << '\n'; cout << "\nNow trying to sort an array\n"; array_of_String sar; sar += "xyz"; sar += "1234"; sar += "abc"; sar += "foo"; sar.sort(); for(int i = 0; i < sar.element_count(); i++) cout << sar[i].cstring() << '\n'; cout << "Done\n";}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -