int SPString::rindex(const SPString & s, int offset) { if (offset == -1) offset = length() - s.length(); else offset = offset - s.length() + 1; if (offset > length() - s.length()) offset = length() - s.length(); for (int i = offset; i >= 0; i--) { if (strncmp(&pstr[i], s, s.length()) == 0) return i; } return -1; }
int SPString::index(const SPString & s, int offset) { if (offset < 0) offset = 0; for (int i = offset; i < length(); i++) { if (strncmp(&pstr[i], s, s.length()) == 0) return i; } return -1; }
// // I know! This is not fast, but it works!! // int SPString::tr(const char *sl, const char *rl, const char *opts) { if (length() == 0 || strlen(sl) == 0) return 0; int cflg = strchr(opts, 'c') != NULL; // thanks Michael int dflg = strchr(opts, 'd') != NULL; int sflg = strchr(opts, 's') != NULL; int cnt = 0, flen = 0; unsigned int i; SPString t; unsigned char lstc = '\0', fr[256]; // build search array, which is a 256 byte array that stores the index+1 // in the search string for each character found, == 0 if not in search memset(fr, 0, 256); for (i = 0; i < strlen(sl); i++) { if (i && sl[i] == '-') { // got a range assert(i + 1 < strlen(sl) && lstc <= sl[i + 1]); // sanity check for (unsigned char c = lstc + 1; c <= sl[i + 1]; c++) { fr[c] = (unsigned char) ++flen; } i++; lstc = '\0'; } else { lstc = sl[i]; fr[sl[i]] = (unsigned char) ++flen; } } unsigned int rlen; // build replacement list if ((rlen = strlen(rl)) != 0) { for (i = 0; i < rlen; i++) { if (i && rl[i] == '-') { // got a range assert(i + 1 < rlen && t[t.length() - 1] <= rl[i + 1]); // sanity check for (char c = t[i - 1] + 1; c <= rl[i + 1]; c++) t += c; i++; } else t += rl[i]; } } // replacement string that is shorter uses last character for rest of // string // unless the delete option is in effect or it is empty while (!dflg && rlen && flen > t.length()) { t += t[t.length() - 1]; // duplicate last character } rlen = t.length(); // length of translation // string // do translation, and deletion if dflg (actually falls out of length of t) // also squeeze translated characters if sflg SPString tmp; // need this in case dflg, and string changes // size for (i = 0; i < (unsigned int) length(); i++) { unsigned int off; if (cflg) { // complement, ie if NOT in // f char rc = (!dflg && t.length() ? t[t.length() - 1] : '\0'); // always use last // character for // replacement if ((off = fr[(*this)[i]]) == 0) { // not in map cnt++; if (!dflg && (!sflg || tmp.length() == 0 || tmp[tmp.length() - 1] != rc)) tmp += rc; } else tmp += (*this)[i]; // just stays the same } else { // in fr so substitute with // t, if no equiv in t then // delete if ((off = fr[(*this)[i]]) > 0) { off--; cnt++; if (rlen == 0 && !dflg && (!sflg || tmp.length() == 0 || tmp[tmp.length() - 1] != (*this)[i])) tmp += (*this)[i]; // stays the same else if (off < rlen && (!sflg || tmp.length() == 0 || tmp[tmp.length() - 1] != t[off])) tmp += t[off]; // substitute } else tmp += (*this)[i]; // just stays the same } } *this = tmp; return cnt; }