2025-05-17

 

說明:寫此代碼無其它用途,純粹為瞭練練手,寫瞭一點,覺得有必要拿來分享。

 

運用泛型的思想編寫,若代碼哪有地方你覺得不爽,請不吝指出。

 

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:huaxin.turtle@gmail.com

 *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;

}

 

 

 

結果如下:

 

 

 

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

 

}

結果如下:

 

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *