#include
#include
namespace myspace
{
class string {
public:
//ctor 声明一个C++字符串
string();
string(const char* s);
string(const char* s, size_t len);
string(const string& rhs);
string(size_t len, char ch);
string(const string rhs, size_t begin, size_t len);
// 重载操作符,复制赋值、比较、增长删除子串
string& operator=(const string& rhs);
bool operator==(const string& rhs);
bool operator>(const string& rhs);
bool operator<(const string& rhs);
bool operator!=(const string& rhs);
string& operator+(const string& rhs);
string& operator-(const string& rhs);
// 删除子串,从begin开始的len长度被删除
string& erase(size_t begin = 0, size_t len = npos);
// 查找在字符串中第一个与str中的某个字符匹配的字符
// 返回它的位置。搜索从index开始,如果没找到就返回string::npos
size_t find_first_of(const basic_string &str, size_t index = 0);
size_t find_first_of(const char *str, size_t index = 0);
size_t find_first_of(const char *str, size_t index, size_t num);
size_t find_first_of(char ch, size_t index = 0);
// 在字符串中查找第一个与str中的字符都不匹配的字符
// 返回它的位置。搜索从index开始。如果没找到就返回string::nops
size_t find_first_not_of( const string &str, size_t index = 0 );
size_t find_first_not_of( const char *str, size_t index = 0 );
size_t find_first_not_of( const char *str, size_t index, size_t num );
size_t find_first_not_of( char ch, size_t index = 0 );
// 在字符串中查找最后一个与str中的某个字符匹配的字符
// 返回它的位置。搜索从index开始。如果没找到就返回string::nops
size_t find_last_of( const string &str, size_t index = npos );
size_t find_last_of( const char *str, size_t index = npos );
size_t find_last_of( const char *str, size_t index, size_t num );
size_t find_last_of( char ch, size_t index = npos );
// 在字符串中查找最后一个与str中的字符都不匹配的字符
// 返回它的位置。搜索从index开始。如果没找到就返回string::nops
size_t find_last_not_of( const string &str, size_t index = npos );
size_t find_last_not_of( const char *str, size_t index = npos );
size_t find_last_not_of( const char *str, size_t index, size_t num );
size_t find_last_not_of( char ch, size_t index = npos );
//dtor
~string();
void copy( char *str, size_t num, size_t index );
//get
size_t size() const;
// from C++11, the data() is same with c_str()
const char* data() const;
const char* c_str() const;
// set & get
char* operator[](size_t index);
private:
char* data_;
size_t len_;
};
}
常用的C++string 函数,我自己实现的:
namespace myspace
{
// ctor 默认构造函数,生成长度为0的空字符串"\0"
// 而不是生成'\0',有利于统一析构
string::string() : len_(0)
{
data_ = new char [1];
*data_ = '\0';
}
// 复制构造C类字符串,并以'\0'结束
string::string( const char* s )
{
if(NULL == s)
{
len_ = 0;
data_ = new char [1];
*data_ = '\0';
}
else
{
len_ = strlen(s);
data_ = new char [len_ + 1];
strcpy( data_, s );
}
}
// 以一定长度(字符串长度和指定长度的最小值)复制构造C类字符串
// size_t会确保传入的长度len为非负数
string::string( const char* s, size_t len )
{
if( NULL == s )
{
len_ = 0;
data_ = new char [1];
*data_ = '\0';
}
else
{
len_ = (strlen(s) < len) ? strlen(s) : len;
data_ = new char [len_ + 1];
strncpy( data_, s, len_ );
*(data_ + len_) = '\0';
}
}
// 复制构造同类型的string
string::string( const string& rhs )
{
len_ = rhs.size();
data_ = new char [len_ + 1];
strcpy( data_, rhs.c_str() );
}
// 以len为长度的ch的拷贝(即有len个ch组成的string)
// 注意:当ch=‘\0’时长度为0
string::string(size_t len, char ch)
{
len_ = (ch) ? len : 0;
data_ = new char [len_ + 1];
for(int i=0; ic_str(), rhs.c_str());
}
// 只写一个其他类似
string& string::operator+(const string& rhs)
{
size_t lenth = len_ + rhs.size() + 1;
char *ptr = new char [lenth];
strcpy(ptr, data_);
strcpy(ptr + len_, rhs.c_str());
delete [] data_;
data_ = ptr;
len_ = lenth;
return *this;
}
// 删除子串
string& string::erase(size_t begin, size_t len)
{
size_t lenth = len_ - len;
char *ptr = new char [lenth];
strncpy(ptr, data_, begin);
strcpy(ptr + begin, data_ + begin + len);
delete [] data_;
data_ = ptr;
len_ = lenth;
return *this;
}
// dtor
string::~string()
{
delete [] data_;
}
// 牺牲效率换取异常安全性
void string::copy(char *str, size_t len, size_t index)
{
char *orig = data_;
char *ptr = new char [len + 1];
strncpy(ptr, str + index, len);
*(ptr + len) = '\0';
data_ = ptr;
delete [] orig;
}
size_t string::size() const
{
return len_;
}
// from C++11, the data() is same with c_str()
const char* string::data() const
{
return c_str();
}
const char* string::c_str() const
{
return data_;
}
char* string::operator[]( size_t index )
{
return ( index > len_ ) ? NULL : data_ + index;
}
}
经过测试,都OK~ 若有问题请提出以便修改;
#include
#include
void test_string1()
{
// test string()
qh::string str;
assert( '\0' == *str[0] );
assert( 0 == str.size() );
assert( '\0' == *str.c_str() );
assert( '\0' == *str.data() );
// test copy assign
str = qh::string();
assert( '\0' == *str[0] );
assert( 0 == str.size() );
assert( '\0' == *str.c_str() );
assert( '\0' == *str.data() );
// test string(cahr *) && copy assign
str = qh::string( "jhsf" );
assert( 'j' == *str[0] );
assert( 4 == str.size() );
assert( 'j' == *str.c_str() );
assert( 'j' == *str.data() );
printf( "%s() all test OK!\n", __FUNCTION__ );
}
void test_string2()
{
// test string(string& s) s=""
qh::string s;
qh::string str_test( s );
assert( '\0' == *str_test[0] );
assert( 0 == str_test.size() );
assert( '\0' == *str_test.c_str() );
assert( '\0' == *str_test.data() );
// test string(string&)
const qh::string str_test2 = "abcdefgfgdgdfgfd";
qh::string str(str_test2);
assert( 16 == str.size() );
assert( 'a' == *str.c_str() );
assert( 'a' == *str.data() );
assert( !strcmp(str.c_str(), str_test2.c_str()) );
// test operator[]
assert( 'd' == *str[3] );
assert( 'f' == *str[7] );
assert( NULL == str[29] );
*str[7] = 'd';
assert( 'd' == *str[7] );
printf( "%s() all test OK!\n", __FUNCTION__ );
}
void test_string3()
{
const char str_test[] = "";
// test string(char* s) s=""
qh::string str(str_test);
assert( '\0' == *str[0] );
assert( 0 == str.size() );
assert( '\0' == *str.c_str() );
assert( '\0' == *str.data() );
// test string(char* s, size_t) s=""
qh::string str2(str_test, 4);
// test operator[]
assert( '\0' == *str2[0] );
assert( 0 == str2.size() );
assert( '\0' == *str2.c_str() );
assert( '\0' == *str2.data() );
printf( "%s() all test OK!\n", __FUNCTION__ );
}
void test_string4()
{
// test string(char*, size_t)
char str_test[] = "^%$^%$**&%*(^^#%";
qh::string str(str_test, 4);
assert( '^' == *str.c_str() );
assert( '^' == *str.data() );
// test operator[]
assert( '^' == *str[3] );
assert( NULL == str[29] );
assert( 4 == str.size() );
*str[2] = '^';
assert( '^' == *str[2] );
// test self copy assign
qh::string str2 = "1234645765";
str2 = str2;
assert(str2.c_str() != NULL);
assert( '1' == *str2[0] );
assert( 10 == str2.size() );
assert( '1' == *str2.c_str() );
assert( '1' == *str2.data() );
printf("%s() all test OK!\n", __FUNCTION__);
}
int main(int argc, char* argv[])
{
//TODO 在这里添加单元测试,越多越好,代码路径覆盖率越全越好
//TODO 单元测试写法请参考INIParser那个项目,不要写一堆printf,要用assert进行断言判断
test_string1();
test_string2();
test_string3();
test_string4();
#ifdef WIN32
system("pause");
#endif
return 0;
}