自制string类(支持宽字符)

说明:写此代码无其它用途,纯粹为了练练手,写了一点,觉得有必要拿来分享。大笑

运用泛型的思想编写,若代码哪有地方你觉得不爽,请不吝指出。害羞

string class referencs :http://www.cplusplus.com/reference/string/string/

欢迎学习交流!转载不忘注明出处(http://blog.csdn.net/zhanxinhang)^_^



头文件 my_string.hpp

/*
 *copy right by ZhanHang,2011.7
 *E-mail:[email protected]
 *QQ:273711460
 *Welcome To My Homepage(http://blog.csdn.net/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;
}


结果如下:

自制string类(支持宽字符)_第1张图片

//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,他是中国人

}

结果如下:

自制string类(支持宽字符)_第2张图片


======= welcome to my HomePage(http://blog.csdn.net/zhanxinhang) to have a communication =======


你可能感兴趣的:(自制string类(支持宽字符))