string.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,411 行 · 第 1/2 页
C
1,411 行
char *pStart = srep->str + pos;
char *pEnd = srep->str + thisLen;
for(; pStart < pEnd; pos++, pStart++) {
if(*pStart == c) {
fpos = pos;
return 1;
}
}
return 0;
}
int String::rfind(char c, size_t& fpos, size_t pos) const
{
size_t thisLen = length();
//
// operations
//
fpos = NPOS;
if(thisLen == 0)
return 0;
if(pos >= thisLen)
pos = thisLen - 1;
// pointers are valid because thisLen > 0
char *pStart = srep->str + pos;
char *pBegin = srep->str;
for(; pStart >= pBegin; pos--, pStart--) {
if(*pStart == c) {
fpos = pos;
return 1;
}
}
return 0;
}
//
// insert
//
String& String::insert(size_t pos, const String& s)
{
KEEPOLD;
//
// preconditions
//
if(pos > length())
strError("String::insert", "OutOfRange");
//
// operations
//
if(this == &s)
return insert(pos, String(s)); // insert into itself
if(s.srep)
doReplace(pos, 0, s.srep->str, s.srep->getLen());
//
// post conditions
//
assert(length() == (s.length() + OLD.length()));
assert(memcmp(cStr() + pos, s.cStr(), s.length()) == 0);
return *this;
}
String& String::insert(size_t pos, const char* cb, size_t n)
{
KEEPOLD;
#ifndef NDEBUG
char *pOLD = 0;
if(cb != 0) {
if(n == NPOS)
n = strlen(cb);
pOLD = new char[n];
assert(pOLD != 0);
memcpy(pOLD, cb, n);
}
#endif
//
// preconditions
//
if(pos > length())
strError("String::insert", "OutOfRange");
if(cb == 0)
strError("String::insert", "InvalidArgument");
//
// operations
//
if(n == NPOS)
n = strlen(cb);
if(n > 0)
doReplace(pos, 0, cb, n);
//
// post conditions
//
assert(length() == (n + OLD.length()));
#ifndef NDEBUG
//
// this asertion is so complicated
// because of hacks like: s.insert(1, s.cStr() + 2)
//
assert(memcmp(cStr() + pos, pOLD, n) == 0);
delete [] pOLD;
#endif
return *this;
}
String& String::insert(size_t pos, char c, size_t rep)
{
KEEPOLD;
//
// preconditions
//
if(pos > length())
strError("String::insert", "OutOfRange");
//
// operations
//
if(rep == 1)
doReplace(pos, 0, &c, 1);
else if(rep > 0)
insert(pos, String(c, rep));
//
// post conditions
//
assert(length() == (rep + OLD.length()));
#ifndef NDEBUG
for(int i = 0; i < rep; i++)
assert(getAt(i + pos) == c);
#endif /* NDEBUG */
return *this;
}
//
// replace
//
String& String::replace(size_t pos, size_t n, const char *cb, size_t len)
{
KEEPOLD;
size_t thisLen = length();
//
// preconditions
//
if(pos > thisLen)
strError("String::replace", "OutOfRange");
if(cb == 0)
strError("String::replace", "InvalidArgument");
//
// operations
//
if(len == NPOS)
len = strlen(cb);
if((pos + n) > thisLen)
n = thisLen - pos;
if(n > 0 || len > 0)
doReplace(pos, n, cb, len);
//
// post conditions
//
assert(length() == (OLD.length() - n + len));
return *this;
}
String& String::replace(size_t pos, size_t n, char c, size_t rep)
{
// this could be implemented more efficiently
// we get all assertions and checks in
// replace(size_t, size_t, const String&);
replace(pos, n, String(c,rep));
return *this;
}
String& String::replace(size_t pos, size_t len, const String& s)
{
KEEPOLD;
size_t thisLen = length();
//
// preconditions
//
if(pos > thisLen)
strError("String::replace", "OutOfRange");
//
// operations
//
if(this == &s) { // if argument string is target
return replace(pos, len, String(s)); // get a copy and call it
// recursively
}
if((pos + len) > thisLen)
len = thisLen - pos;
doReplace(pos, len, s.getStr(), s.length());
//
// post conditions
//
assert(length() == (OLD.length() - len + s.length()));
return *this;
}
//
// remove
//
String& String::remove(size_t pos, size_t n)
{
KEEPOLD;
size_t thisLen = length();
//
// preconditions
//
if(pos > length())
strError("String::remove", "OutOfRange");
//
// operations
//
if(n == NPOS || (pos + n) > thisLen)
n = thisLen - pos;
if(n > 0)
doReplace(pos, n, "", 0);
//
// post conditions
//
assert(length() == (OLD.length() - n));
return *this;
}
String& String::getRemove(char& c, size_t pos)
{
KEEPOLD;
//
// preconditions
//
if(pos >= length())
strError("String::getRemove", "OutOfRange");
//
// operations
//
c = getAtRaw(pos);
doReplace(pos, 1, "", 0);
//
// post conditions
//
assert(length() == (OLD.length() - 1));
assert(OLD.getAt(pos) == c);
return *this;
}
String& String::getRemove(String& s, size_t pos, size_t n)
{
KEEPOLD;
size_t thisLen = length();
//
// preconditions
//
if(pos > thisLen)
strError("String::getRemove", "OutOfRange");
//
// operations
//
if(n == NPOS || (pos + n) > thisLen)
n = thisLen - pos;
s = substr(pos, n);
doReplace(pos, n, "", 0);
//
// post conditions
//
assert(length() == (OLD.length() - s.length()));
assert(s == OLD.substr(pos, n));
return *this;
}
//
// substring
//
String String::substr(size_t pos, size_t n) const
{
size_t thisLen = length();
//
// preconditions
//
if(pos > thisLen)
strError("String::substr", "OutOfRange");
//
// operations
//
if(n == NPOS || (pos + n) > thisLen)
n = thisLen - pos;
if(n == 0)
return String();
else
return String(srep->str + pos, n);
}
//
// ANSI C functionality
//
int String::findFirstOf(const String& s, size_t& fpos, size_t pos) const
{
return findFirstOf(s.getStr(), fpos, pos, s.length());
}
int String::findFirstOf(const char *cb, size_t& fpos, size_t pos, size_t n)
const
{
size_t thisLen = length();
//
// preconditions
//
if(cb == 0)
strError("String::findFirstOf", "InvalidArgument");
//
// operations
//
fpos = NPOS;
if(thisLen == 0 || pos >= thisLen)
return 0;
if(n == NPOS)
n = strlen(cb);
// pointer are valid because thisLen > 0 => srep != 0
char *pStart = srep->str + pos;
char *pEnd = srep->str + thisLen;
for(; pStart < pEnd; pos++, pStart++) {
if(memchr(cb, *pStart, n) != 0) {
fpos = pos;
return 1;
}
}
return 0;
}
int String::findFirstNotOf(const String& s, size_t& fpos, size_t pos) const
{
return findFirstNotOf(s.getStr(), fpos, pos, s.length());
}
int String::findFirstNotOf(const char *cb, size_t& fpos, size_t pos, size_t n)
const
{
size_t thisLen = length();
//
// preconditions
//
if(cb == 0)
strError("String::findFirstOf", "InvalidArgument");
//
// operations
//
fpos = NPOS;
if(thisLen == 0 || pos >= thisLen)
return 0;
if(n == NPOS)
n = strlen(cb);
// pointer are valid because thisLen > 0 => srep != 0
char *pStart = srep->str + pos;
char *pEnd = srep->str + thisLen;
for(; pStart < pEnd; pos++, pStart++) {
if(memchr(cb, *pStart, n) == 0) {
fpos = pos;
return 1;
}
}
return 0;
}
//
// copy to C buffer
//
size_t String::copy(char *cb, size_t n, size_t pos, size_t len) const
{
size_t thisLen = length();
//
// preconditions
//
if(pos > thisLen)
strError("String::copy", "OutOfRange");
if(cb == 0)
strError("String::copy", "InvalidArgument");
//
// operations
//
if(len > (thisLen - pos))
len = thisLen - pos;
if(n < len)
len = n;
if(len > 0)
memcpy(cb, srep->str + pos, len);
return (len);
}
//
// get pointer to internal C-String
//
const char* String::cStr() const
{
const char *p = "";
//
// operations
//
if(srep)
p = srep->cPtr();
return p;
}
//
// capacity
//
void String::reserve(size_t n) const
{
size_t thisLen = length();
String::StringRep* rep;
// guarantees uniqueness !!
if(n < thisLen)
n = thisLen;
if(n > 0)
rep = StringRep::getNew(thisLen, n, srep->str);
else
rep = 0;
((String*)this)->refDec();
((String*)this)->srep = rep; // casting constness away to use
// meaningwise constness
}
//
// friend functions
//
ostream& operator<<(ostream& os, const String& s)
{
//
// operations
//
if(s.srep) {
os.write(s.getStr(), s.length());
}
return os;
}
const int lBufSize = 32;
istream& operator>>(istream& is, String& s)
{
char aChar;
char buffer[lBufSize];
int bufpos = 0;
// I am nor very experienced in iostream
// please give me some comments
s = "";
if(is.good()) {
if(is.flags() & ios::skipws)
is >> ws;
if(is) {
for(;;) {
is.get(aChar);
if(!is)
break;
if(isspace(aChar)) {
is.putback(aChar);
break;
}
if(bufpos >= lBufSize) {
s.append(buffer, lBufSize);
bufpos = 0;
}
buffer[bufpos++] = aChar;
}
}
}
if(bufpos > 0)
s.append(buffer, bufpos);
if(is.eof() && s.length() != 0)
is.clear(0); // ??
return is;
}
istream& getline(istream& is, String& s, char c)
{
char aChar;
char buffer[lBufSize];
int bufpos = 0;
s = "";
if(is.good()) {
for(;;) {
is.get(aChar);
if(!is)
break;
if(aChar == c) { // get and consume eol character !!
break;
}
if(bufpos >= lBufSize) {
s.append(buffer, lBufSize);
bufpos = 0;
}
buffer[bufpos++] = aChar;
}
}
if(bufpos > 0)
s.append(buffer, bufpos);
if(is.eof() && s.length() != 0)
is.clear(0); // ??
return is;
}
//
// string add functions
//
String operator+(const String& s1, const String& s2)
{
//
// operations
//
return String(s1.getStr(), s1.length(), s2.getStr(), s2.length());
}
String operator+(const String& s, const char* cs)
{
//
// preconditions
//
if(cs == 0)
strError("operator+", "InvalidArgument");
//
// operations
//
return String(s.getStr(), s.length(), cs, strlen(cs));
}
String operator+(const char* cs, const String& s)
{
//
// preconditions
//
if(cs == 0)
strError("operator+", "InvalidArgument");
//
// operations
//
return String(cs, strlen(cs), s.getStr(), s.length());
}
String operator+(const String& s, char c)
{
//
// operations
//
return String(s.getStr(), s.length(), &c, 1);
}
String operator+(char c, const String& s)
{
//
// operations
//
return String(&c, 1, s.getStr(), s.length());
}
int compare(const String& s1, const String& s2)
{
return s1.compare(s2);
}
int compare(const String& s, const char* cs)
{
//
// preconditions
//
if(cs == 0)
strError("compare", "InvalidArgument");
//
// operations
//
return s.compare(cs, strlen(cs));
}
int compare(const char *cs, const String& s)
{
//
// preconditions
//
if(cs == 0)
strError("compare", "InvalidArgument");
//
// operations
//
return -s.compare(cs, strlen(cs));
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?