说明:写此代码无其它用途,纯粹为了练练手,写了一点,觉得有必要拿来分享。
运用泛型的思想编写,若代码哪有地方你觉得不爽,请不吝指出。
string class referencs :http://www.cplusplus.com/reference/string/string/
欢迎学习交流!转载不忘注明出处(http://blog.youkuaiyun.com/zhanxinhang)^_^
头文件 my_string.hpp
/*
*copy right by ZhanHang,2011.7
*E-mail:huaxin.turtle@gmail.com
*QQ:273711460
*Welcome To My Homepage(http://blog.youkuaiyun.com/zhanxinhang)!
*/
#ifndef MY_STRING_HPP
#define MY_STRING_HPP
#include <malloc.h>
#include <cstring>
#include <cassert>
#include <cwchar>
template<typename charT>
class myString
{
public:
typedef charT* iterator;
private:
size_t M_length;
size_t M_storage_size;
iterator M_begin;
iterator M_end;
private://allocator
iterator alloc(size_t n);
public://constructor and destructor
myString(const charT*);
myString();
~myString();
public://operator=
myString& operator= (const myString&);
myString& operator= (const charT*);
myString& operator= (charT);
public://iterator
const iterator begin()const;
const iterator end()const;
public://capacity
const size_t size()const;
const size_t max_size()const;
void resize (size_t ,charT);
void resize (size_t n);
public://element access
charT& operator[](size_t);
public:// String operations
const charT* c_str()const;
size_t copy (charT* s, size_t n, size_t pos=0)const;
size_t find (const myString& str,size_t pos=0)const;
};//class myString
/
// constructor //
/
template<typename charT>
inline myString<charT>::myString(const charT* str)
:M_length(strlen((char*)str)/sizeof(charT)),
M_storage_size(M_length+M_length/5+1),
M_begin(alloc(M_storage_size)),
M_end(M_begin+M_length)
{
assert(M_length<max_size());
strcpy((char*)M_begin,(char*)str);
*M_end='\0';
}
template<typename charT>
inline myString<charT>::myString()
:M_length(0),
M_begin(alloc(1)),
M_end(0)
{
*M_begin='\0';
}
// destructor //
template<typename charT>
inline myString<charT>::~myString()
{
free(M_begin);
}
///
// operator= //
///
template<typename charT>
inline myString<charT>& myString<charT>::operator= (const myString &str)
{
M_length=str.size();
assert(M_length<max_size());
if(M_storage_size<=M_length)//动态分配存储空间
{
free(M_begin);
M_begin=alloc(M_length+M_length/5+1);
}
strcpy((char*)M_begin,(char*)str.c_str());
M_end=M_begin+M_length;
return *this;
}
template<typename charT>
inline myString<charT>& myString<charT>::operator= (const charT* pstr)
{
M_length=strlen((char*)pstr)/sizeof(charT);
assert(M_length<max_size());
if(M_storage_size<=M_length)
{
free(M_begin);
M_begin=alloc(M_length+M_length/5+1);
}
strcpy((char*)M_begin,(char*)pstr);
M_end=M_begin+M_length;
return *this;
}
template<typename charT>
inline myString<charT>& myString<charT>::operator= (charT c)
{
M_length=1;
M_end=M_begin+M_length;
if(M_storage_size<=1)
{
free(M_begin);
M_begin=alloc(2);
}
*M_begin=c;
return *this;
}
//
// iterator //
//
template<typename charT>
inline const typename myString<charT>::iterator myString<charT>::begin()const
{
return M_begin;
}
template<typename charT>
inline const typename myString<charT>::iterator myString<charT>::end()const
{
return M_end;
}
//
// capacity //
//
template<typename charT>
inline const size_t myString<charT>::max_size()const
{
return size_t(-1) / sizeof(charT *) - 1;
}
template<typename charT>
inline const size_t myString<charT>::size()const
{
return M_length;
}
template<typename charT>
void myString<charT>::resize(size_t n,charT c)
{
charT *tmp = M_begin;
int i;
M_begin=alloc(n+1);
M_end=M_begin+n;
memcpy((char*)M_begin,(char*)tmp,(n<M_length?n:M_length)*sizeof(charT));
M_length=strlen((char*)M_begin)/sizeof(charT);
for(i=M_length;i<n;i++)
{
M_begin[i]=c;
}
*M_end='\0';
free(tmp);
}
template<typename charT>
void myString<charT>::resize(size_t n)
{
charT *tmp=M_begin;
M_begin=alloc(n+1);
M_end=M_begin+n;
memcpy((char*)M_begin,(char*)tmp,(n<M_length?n:M_length)*sizeof(charT));
M_length=strlen((char*)M_begin)/sizeof(charT);
free(tmp);
}
// element access //
template<typename charT>
charT& myString<charT>::operator[](size_t pos)
{
return M_begin[pos];
}
///
// allocator //
///
template<typename charT>
inline typename myString<charT>::iterator myString<charT>::alloc(size_t n)
{
M_storage_size=n;
return (charT*)calloc(n,sizeof(charT));
}
///
// String operations //
///
template<typename charT>
inline const charT* myString<charT>::c_str()const
{
return M_begin;
}
template<typename charT>
size_t myString<charT>::copy(charT *s, size_t n,size_t pos)const
{
size_t i,j;
assert(pos<M_length);
for(i=0,j=pos;i<n&&j<M_length;i++,j++)
{
s[i]=M_begin[j];
}
return i;
}
template<typename charT>
inline size_t myString<charT>::find (const myString<charT>& str,size_t pos)const
{
char* p=strstr((char*)M_begin,(char*)str.c_str());
return (p-(char*)M_begin)/sizeof(charT)+1;
}
typedef myString<char> String;
typedef myString<wchar_t> WString;
#endif
//vs环境下的测试
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <iostream>
#include <locale.h>
#include "my_string.hpp"
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "chs");
String st="zh";
String str=st;
printf("str=%s\n",str.c_str());//zxh
wchar_t *w=L"中国人";
WString wstr(w);
wprintf(L"%ls\n",wstr.c_str());//中国人
str="zhanhang";
wstr=L"是中国人";
printf("%s",str.c_str());
wprintf(L"%ls\n",wstr.c_str());//zhanhang是中国人
//operator[] method test
printf("%c\n",str[2]);//a
wprintf(L"%ls\n",&wstr[3]);//人
//iterator method test
String::iterator it;
for(it=str.begin();it!=str.end();it++)
{
printf("%c",*it);
} //zhanhang
printf("\n");
WString::iterator wit=wstr.begin();
wit++;
wprintf(L"%ls\n",wit);//中国人
//resize method test
wstr.resize(6,wstr[0]);
wprintf(L"%ls\n",wstr.c_str()); //是中国人是是
str.resize(2);
printf("%s\n",str.c_str());//zh
str.resize(7,'*');
printf("%s\n",str.c_str());//zh*****
//find method test
str="zhan xin hang";
wstr=L"他是中国人";
String key="xin";
WString wkey=L"中国人";
printf("%d\n",str.find(key)); //6
printf("%d\n",wstr.find(wkey)); //3
//copy method test
wchar_t wbuff[20]={0};
char buff[20]={0};
str.copy(buff,2);
wstr.copy(wbuff,5);
printf("%s",buff);
wprintf(L"%ls\n",wbuff);//zh他是中国人
getch();
return 0;
}
结果如下:
//g++环境下的测试
#include <iostream>
#include <cstdio>
#include"my_string.hpp"
int main()
{
String st="zh";
String str=st;
printf("str=%s\n",str.c_str());//zxh
wchar_t *w=(wchar_t*)"中国人";
WString wstr(w);
printf("%s\n",wstr.c_str());//中国人
str="zhanhang";
wstr=(wchar_t*)"是中国人";
printf("%s",str.c_str());
printf("%s\n",wstr.c_str());//zhanhang是中国人
//operator[] method test
printf("%c\n",str[2]);//a
printf("%s\n",&wstr[3]);//人
//iterator method test
String::iterator it;
for(it=str.begin();it!=str.end();it++)
{
printf("%c",*it);
} //zhanhang
printf("\n");
WString::iterator wit=wstr.begin();
wit++;
printf("%s\n",wit);//中国人
//resize method test
wstr.resize(6,wstr[0]);
printf("%s\n",wstr.c_str()); //是中国人是是
str.resize(2);
printf("%s\n",str.c_str());//zh
str.resize(7,'*');
printf("%s\n",str.c_str());//zh*****
//find method test
str="zhan xin hang";
wstr=(wchar_t*)"他是中国人";
String key="xin";
WString wkey=(wchar_t*)"中国人";
std::cout<<str.find(key)<<std::endl; //6
std::cout<<wstr.find(wkey)<<std::endl; //3
//copy method test
wchar_t wbuff[20]={0};
char buff[20]={0};
str.copy(buff,2);
wstr.copy(wbuff,5);
printf("%s,%s\n",buff,wbuff);//zh,他是中国人
}
结果如下:
======= welcome to my HomePage(http://blog.youkuaiyun.com/zhanxinhang) to have a communication =======