本人写过与此相关的两篇博客,一个是<cstring>头文件的实现,还有一个是<cwchar>的实现。这里的char_traits模板类在此基础上实现。

为了方便。将源码一起封装于名字空间mystd里。

代码例如以下!!!

// 此文件命名为   "char_traits.h"

// vs2012 调试通过
#pragma once
#ifndef MYSTD_CHAR_TRAITS_H
#define MYSTD_CHAR_TRAITS_H #include<cstddef> // std::size_t
#include<cassert> #pragma push_macro("EOF")
#undef EOF
#define EOF (-1) #pragma push_macro("WEOF")
#undef WEOF
#define WEOF (unsigned short)(0xFFFF) #define MYSTD_BEGIN namespace mystd{
#define MYSTD_END } #ifdef __cplusplus MYSTD_BEGIN //cstring.h
typedef std::size_t size_type;
typedef unsigned char UCHAR;
// C语言版本号,void * memchr(const void *,int,size_type);
inline const void* memchr(const void *pointer,int val, size_type num)
{
assert(pointer != 0);
UCHAR *ptr = (UCHAR*)pointer;
for(size_type i = 0; i < num; ++i)
{
if(*ptr == val)
break;
++ptr;
}
return ptr;
}
inline void* memchr(void *pointer, int val,size_type num) //c++重载
{
assert(pointer != 0);
return (void*)mystd::memchr((const void*)pointer,val,num); // 转调
}
inline size_type strlen(const char *str)
{
assert(str != 0);
size_type count = 0;
while(*str++)
++count;
return count;
} inline void* memmove(void *destination,const void *source, size_type num)
{ // 对于memmove函数的实现,c++之父在《c++ 程序设计语言》(十周年中文纪念版第16章开篇)
//就说过,此函数无法由c++语言本身达到最优实现,实际应用时还是用标准库吧!
assert(destination != 0 && source != 0);
if(destination == source || num == 0)
return destination;
UCHAR *des = (UCHAR*)destination;
const UCHAR *src = (UCHAR*)source;
if(des < src || des >= src + num)
{
while(num--)
*des++ = *src++;
return destination;
}
des += num;
src += num;
while(num--) // 倒序复制
*--des = *--src;
return destination;
}
inline void* memcpy(void *destination,const void *source, size_type num)
{
assert(destination != 0 && source != 0);
return mystd::memmove(destination,source,num);
}
inline int memcmp(const void *pointer_1,const void *pointer_2,size_type num)
{
assert(pointer_1 != 0 && pointer_2 != 0);
const UCHAR *ptr_1 = (UCHAR*)pointer_1;
const UCHAR *ptr_2 = (UCHAR*)pointer_2;
while(num-- && *ptr_1 == *ptr_2)
++ptr_1,++ptr_2;
if(num == size_type(-1))
return 0;
else
return *ptr_1 - *ptr_2;
}
inline void* memset(void *pointer,int val,size_type num)
{
assert(pointer != 0);
UCHAR *ptr = (UCHAR*)pointer;
while(num--)
*ptr++ = val;
return pointer;
}
inline char* strcat(char *destination,const char *source)
{
assert(destination != 0 && source != 0);
char *ptr = destination + mystd::strlen(destination);
while(*ptr++ = *source++);
return destination;
}
inline char *strncat(char *destination,const char *source,size_type num)
{
assert(destination != 0 && source != 0);
char *ptr = destination + mystd::strlen(destination);
while(num-- && *source)
*ptr++ = *source++;
*ptr = 0; // null-character 复制
return destination;
}
inline char *strcpy(char *destination,const char *source)
{
assert(destination != 0 && source != 0);
char *des = destination;
while(*des++ = *source++);
return destination; // null-character被复制
}
inline char *strncpy(char *destination,const char *source,size_type num)
{
assert(destination != 0 && source != 0);
char *des = destination;
while(num--)
*des++ = *source++;
return destination; // null-character可能没有被复制
}
inline int strcmp(const char *str1,const char *str2)
{
assert(str1 != 0 && str2 != 0);
while(*str1 && *str1 == *str2)
++str1, ++str2;
return *str1 - *str2;
}
inline int strncmp(const char *str1,const char *str2,size_type num)
{
assert(str1 != 0 && str2 != 0);
while(num-- && *str1 && *str1 == *str2)
++str1, ++str2;
if(num == size_type(-1)) // 包括了num == 0的情况
return 0;
else
return *str1 - *str2;
}
//C语言仅仅有一个版本号 char* strchr(const char *, int);
inline const char* strchr(const char *str,int character)
{
assert(str != 0);
// 语言标准规定character 为int,这里转换一下
const char chr = *(char*)&character;
while(*str && *str != chr)
++str;
if(*str)
return str;
else
return 0;
}
inline char* strchr(char *str,int character) //c++重载
{
assert(str != 0);
return (char*)mystd::strchr((const char*)str,character);
}
inline const char* strrchr(const char *str,int character)
{ //这里的character 可能包括null-character
assert(str != 0);
// 语言标准规定character 为int,这里转换一下
const char chr = *(char*)&character;
size_type len = mystd::strlen(str);
const char *ptr = str + len;
if(chr == 0)
return ptr;
--ptr;
while(len--)
if(*ptr == chr)
return ptr;
else
--ptr;
return 0; //无匹配的字符
}
inline char* strrchr(char *str,int character)
{
assert(str != 0);
return (char*)mystd::strrchr((const char*)str,character); // 转调
}
//c语言版本号char* strstr(const char *,const char*);
inline const char* strstr(const char* str1,const char* str2)
{
assert(str1 != 0 && str2 != 0);
size_type len_1 = mystd::strlen(str1);
size_type len_2 = mystd::strlen(str2);
if(len_1 < len_2)
return 0;
const char *search_last = str1 + (len_1 - len_2);
while(str1 <= search_last)
{
if(mystd::strncmp(str1,str2,len_2) == 0)
return str1;
else
++str1;
}
return 0;
}
inline char* strstr(char *str1,const char *str2) //c++重载
{
assert(str1 != 0 && str2 != 0);
return (char*)mystd::strstr((const char*)str1,str2);
}
inline bool is_inside(const char *str,char chr) // 辅助函数,内部使用
{
assert(str != 0);
while(*str)
{
if(*str == chr)
return true;
else
++str;
}
return false;
}
inline size_type strspn(const char* str1,const char *str2)
{
assert(str1 != 0 && str2 != 0);
size_type count = 0;
while(*str1 && is_inside(str2,*str1))
++count, ++str1;
return count;
}
inline size_type strcspn(const char* str1,const char *str2)
{
assert(str1 != 0 && str2 != 0);
size_type count = 0;
while(*str1 && !is_inside(str2,*str1))
++count, ++str1;
return count;
}
// c语言版本号char* strpbrk(const char *,const char *);
inline const char* strpbrk(const char *str1,const char *str2)
{
assert(str1 != 0 && str2 != 0);
while(*str1 && !is_inside(str2,*str1))
++str1;
if(*str1 == 0)
return 0;
else
return str1;
}
inline char* strpbrk(char *str1,const char *str2) //c++重载
{
assert(str1 != 0 && str2 != 0);
return (char*)strpbrk((const char*)str1,str2); //转调
}
inline char* strtok(char *str,const char *delim)
{
#ifdef _DEBUG
static bool first_switch = false;
if(!first_switch)
assert(str != 0);
assert(delim != 0);
#endif
static char * p_location = 0; //记录搜索起始位置
if(str)
p_location = str;
char *ptr = mystd::strpbrk(p_location,delim);
char *temp = p_location;
if(ptr == 0) // 找不到分隔符,默觉得搜索结束
{
#ifdef _DEBUG
first_switch = false; // 搜索结束。first_switch置为false
#endif
p_location = 0; // 搜索结束。p_location 复位
return temp;
}
#ifdef _DEBUG
first_switch = true;
#endif
*ptr = 0;
p_location = ptr + 1; // 位置更新
return temp;
}
inline size_type strxfrm(char *destination,const char *source,size_type num);
inline int strcoll(const char *str1,const char *str2);
inline char* strerror(int errnum); MYSTD_END // end of namespace mystd MYSTD_BEGIN //宽字符版本号
typedef std::size_t size_type;
typedef wchar_t char_type;
inline size_type wcslen(const char_type* wcs)
{
assert(wcs != 0);
size_type count = 0;
while(*wcs++)
++count;
return count;
}
inline char_type* wcscat(char_type* destination,const char_type *source)
{
assert(destination != 0 && source != 0);
char_type *des = destination + mystd::wcslen(destination);
while(*des++ = *source++);
return destination;
}
inline char_type* wcsncat(char_type* destination,const char_type *source,size_type num)
{
assert(destination != 0 && source != 0);
char_type *des = destination + mystd::wcslen(destination);
while(num-- && *source)
*des++ = *source++;
*des = 0;
return destination;
}
inline char_type* wcscpy(char_type *destination,const char_type *source)
{
assert(destination != 0 && source != 0);
char_type *des = destination;
while(*des++ = *source++);
return destination;
}
inline char_type* wcsncpy(char_type *destination,const char_type *source,size_type num)
{
assert(destination != 0 && source != 0);
char_type *des = destination;
while(num--)
*des++ = *source++;
return destination; // 可能不包括null wide character
}
inline int wcscmp(const char_type *wcs1,const char_type *wcs2)
{
assert(wcs1 != 0 && wcs2 != 0);
while(*wcs1 && *wcs1 == *wcs2)
++wcs1, ++wcs2;
return *wcs1 - *wcs2;
}
inline int wcsncmp(const char_type *wcs1,const char_type *wcs2,size_type num)
{
assert(wcs1 != 0 && wcs2 != 0);
while(num-- && *wcs1 && *wcs1 == *wcs2)
++wcs1, ++wcs2;
if(num == size_type(-1)) // 包括了num == 0的情况
return 0;
else
return *wcs1 - *wcs2;
}
inline const char_type* wmemchr(const char_type* pointer,char_type val,size_type num)
{
assert(pointer != 0);
char_type *ptr = (char_type*)pointer;
for(size_type i = 0; i < num; ++i)
{
if(*ptr == val)
break;
++ptr;
}
return ptr;
}
inline char_type* wmemchr(char_type* pointer,char_type val,size_type num)
{
assert(pointer != 0);
return (char_type*)wmemchr((const char_type*)pointer,val,num);
}
inline int wmemcmp(const char_type *ptr_1,const char_type *ptr_2,size_type num)
{
assert(ptr_1 != 0 && ptr_2 != 0);
while(num-- && *ptr_1 == *ptr_2)
++ptr_1, ++ptr_2;
if(num == size_type(-1))
return 0;
else
return *ptr_1 - *ptr_2;
}
inline char_type* wmemset(char_type *pointer,char_type val,size_type num)
{
assert(pointer != 0);
char_type *ptr = pointer;
while(num--)
*ptr++ = val;
return pointer;
}
inline char_type* wmemmove(char_type *destination,const char_type *source,size_type num)
{
assert(destination != 0 && source != 0);
if(destination == source || num == 0)
return destination;
char_type *des = (char_type*)destination;
const char_type *src = (char_type*)source;
if(des < src || des >= src + num)
{
while(num--)
*des++ = *src++;
return destination;
}
des += num;
src += num;
while(num--) // 倒序复制
*--des = *--src;
return destination;
}
inline char_type* wmemcpy(char_type *destination,const char_type *source,size_type num)
{
assert(destination != 0 && source != 0);
return mystd::wmemmove(destination,source,num);
}
inline bool w_is_inside(const char_type *wcs,char_type val) // 辅助函数。内部使用
{
assert(wcs != 0);
while(*wcs)
{
if(*wcs == val)
return true;
else
++wcs;
}
return false;
}
inline size_type wcsspn(const char_type *wcs1,const char_type *wcs2)
{
assert(wcs1 != 0 && wcs2 != 0);
size_type count = 0;
while(*wcs1 && w_is_inside(wcs2,*wcs1))
++count, ++wcs1;
return count;
}
inline size_type wcscspn(const char_type *wcs1,const char_type *wcs2)
{
assert(wcs1 != 0 && wcs2 != 0);
size_type count = 0;
while(*wcs1 && !w_is_inside(wcs2,*wcs1))
++count, ++wcs1;
return count;
}
inline const char_type* wcsstr(const char_type *wcs1,const char_type *wcs2)
{
assert(wcs1 != 0 && wcs2 != 0);
size_type len_1 = mystd::wcslen(wcs1);
size_type len_2 = mystd::wcslen(wcs2);
if(len_1 < len_2)
return 0;
const char_type *search_last = wcs1 + (len_1 - len_2);
while(wcs1 <= search_last)
{
if(mystd::wcsncmp(wcs1,wcs2,len_2) == 0)
return wcs1;
else
++wcs1;
}
return 0;
}
inline char_type* wcsstr(char_type *wcs1,const char_type *wcs2)
{
assert(wcs1 != 0 && wcs2 != 0);
return (char_type*)mystd::wcsstr((const char_type*)wcs1,wcs2);
} inline const char_type* wcschr(const char_type *wcs,char_type val)
{
assert(wcs != 0);
while(*wcs && *wcs != val)
++wcs;
if(*wcs)
return wcs;
else
return 0;
}
inline char_type* wcschr(char_type *wcs,char_type val)
{
assert(wcs != 0);
return (char_type*)mystd::wcschr((const char_type*)wcs,val);
}
inline const char_type* wcsrchr(const char_type *wcs,char_type val)
{ // val可能为null wide character
assert(wcs != 0);
size_type len = mystd::wcslen(wcs);
const char_type *ptr = wcs + len;
if(val == 0)
return ptr;
--ptr;
while(len--)
if(*ptr == val)
return ptr;
else
--ptr;
return 0; //无匹配的字符
}
inline char_type* wcsrchr(char_type *wcs,char_type val)
{ //val可能为null wide character
assert(wcs != 0);
return (char_type*)mystd::wcsrchr((const char_type*)wcs,val); // 转调
} inline const char_type* wcspbrk(const char_type *wcs1,const char_type *wcs2)
{
assert(wcs1 != 0 && wcs2 != 0);
while(*wcs1 && !w_is_inside(wcs2,*wcs1))
++wcs1;
if(*wcs1 == 0)
return 0;
else
return wcs1;
}
inline char_type* wcspbrk(char_type *wcs1,const char_type *wcs2)
{
assert(wcs1 != 0 && wcs2 != 0);
return (char_type*)mystd::wcspbrk((const char_type*)wcs1,wcs2);
}
inline char_type* wcstok(char_type *wcs,const char_type *delim)
{
#ifdef _DEBUG
static bool first_switch = false;
if(!first_switch)
assert(wcs != 0);
assert(delim != 0);
#endif
static char_type * p_location = 0; //记录搜索起始位置
if(wcs)
p_location = wcs;
char_type *ptr = mystd::wcspbrk(p_location,delim);
char_type *temp = p_location;
if(ptr == 0) // 找不到分隔符,默觉得搜索结束
{
#ifdef _DEBUG
first_switch = false; // 搜索结束,first_switch置为false
#endif
p_location = 0; // 搜索结束,p_location 复位
return temp;
}
#ifdef _DEBUG
first_switch = true;
#endif
*ptr = 0;
p_location = ptr + 1; // 位置更新
return temp;
}
inline size_type wcsxfrm(char_type *destination,const char_type *source,size_type num); MYSTD_END MYSTD_BEGIN
typedef unsigned short wint_t;
template<class charT>
struct char_traits{
typedef std::size_t size_type;
}; template<> // char特化
struct char_traits<char>{
typedef int int_type;
typedef char char_type;
public:
static size_type length(const char_type *str) throw()
{
assert(str != 0);
return mystd::strlen(str);
} static void assign(char_type& chr,const char_type& val) throw()
{
chr = val;
}
static char_type assign(char_type *ptr,size_type num,char_type chr) throw()
{
assert(ptr != 0);
mystd::memset(ptr,chr,num);
return chr;
}
static int compare(const char_type *str1,const char_type *str2,size_type num) throw()
{
assert(str1 != 0 && str2 != 0);
return mystd::strncmp(str1,str2,num); // 注意C风格字符串
}
static char_type* move(char_type *des,const char_type *src,size_type num) throw()
{
assert(des != 0 && src != 0);
#ifdef _DEBUG
return (char_type*)mystd::memmove(des,src,num);
#else
return (char_type*)std::memmove(des,src,num); // 标准库版本号效率更高
#endif
}
static char_type* copy(char_type *des,const char_type *src,size_type num) throw()
{
assert(des != 0 && src != 0);
#ifdef _DEBUG
return (char_type*)mystd::memcpy(des,src,num);
#else
return (char_type*)std::memcpy(des,src,num); // 标准库版本号效率更高
#endif
}
static bool eq(const char_type& chr_1,const char_type& chr_2)
{
return chr_1 == chr_2;
}
static const char_type* find(const char_type* ptr,size_t num,const char_type& chr)
{
assert(ptr != 0);
while(num-- && *ptr != chr)
++ptr;
if(*ptr == chr && num != size_type(-1)) // 不依赖于null character
return ptr;
else
return 0;
}
static char_type to_char_type(const int_type& chr) throw()
{
assert(chr < 0xFF);
return *(char_type*)&chr;
}
static int_type to_int_type(const char_type& chr) throw()
{
return static_cast<char_type>(chr);
}
static int_type eof() throw()
{
return EOF;
}
}; template<> // 宽字符版本号
struct char_traits<wchar_t>{
typedef wint_t int_type;
typedef wchar_t char_type;
public:
static size_type length(const char_type *wcs) throw()
{
return mystd::wcslen(wcs);
}
static void assign(char_type& wc,const char_type& val) throw()
{
wc = val;
}
static char_type assign(char_type *ptr,size_type num,char_type wc) throw()
{
assert(ptr != 0);
while(num--)
*ptr++ = wc;
return wc;
}
static int compare(const char_type *wcs1,const char_type *wcs2,size_type num) throw()
{
assert(wcs1 != 0 && wcs2 != 0);
return mystd::wcsncmp(wcs1,wcs2,num);
}
static char_type* move(char_type *des,const char_type *src,size_type num) throw()
{
assert(des != 0 && src != 0);
#ifdef _DEBUG
return (char_type*)mystd::wmemmove(des,src,num);
#else
return (char_type*)std::wmemmove(des,src,num); // 标准库版本号效率更高
#endif
}
static char_type* copy(char_type *des,const char_type *src,size_type num) throw()
{
assert(des != 0 && src != 0);
#ifdef _DEBUG
return (char_type*)mystd::wmemcpy(des,src,num);
#else
return (char_type*)std::wmemcpy(des,src,num); // 标准库版本号效率更高
#endif
}
static bool eq(const char_type& wc_1,const char_type& wc_2)
{
return wc_1 == wc_2;
}
static const char_type* find(const char_type* ptr,size_t num,const char_type& wc)
{
assert(ptr != 0);
while(*ptr && num-- && *ptr != wc)
++ptr;
if(*ptr == wc)
return ptr;
else
return 0;
}
static char_type to_char_type(const int_type& wc) throw()
{
assert(wc < 0xFFFF);
return wc;
}
static int_type to_int_type(const char_type& wc) throw()
{
assert(wc < 0xFFFF);
return wc;
}
static int_type eof() throw()
{
return WEOF;
}
}; MYSTD_END // end of namespace mystd
#endif // __cplusplus
#pragma pop_macro("WEOF")
#pragma pop_macro("EOF")
#endif // MYSTD_CHAR_TRAITS_H

希望高手批评指正。!!

c++ char_traits模板类的实现!!!的更多相关文章

  1. C++类模板和模板类

    C++ 中有一个重要特性,那就是模板类型.类似于Objective-C中的泛型.C++通过类模板来实现泛型支持. 1 基础的类模板 类模板,可以定义相同的操作,拥有不同数据类型的成员属性. 通常使用t ...

  2. 单链表的C++实现(采用模板类)

    采用模板类实现的好处是,不用拘泥于特定的数据类型.就像活字印刷术,制定好模板,就可以批量印刷,比手抄要强多少倍! 此处不具体介绍泛型编程,还是着重叙述链表的定义和相关操作.  链表结构定义 定义单链表 ...

  3. 模板类 error LNK2019: 无法解析的外部符号

    如果将类模板的声明和实现写在两个独立的文件中,在构建时会出现"error LNK2019: 无法解析的外部符号 "的错误. 解决方法有: 第一种方法,就是把类模板中成员函数的声明和 ...

  4. 关于g++编译模板类的问题

    今天搞了我接近4个小时,代码没错,就是调试没有通过,无论怎么也没有想到是编译器的问题 g++不支持c++模板类 声明与实现分离,都要写到.h文件里面. 以后记住了.

  5. C++11特性(模板类 initializer_list)

    [1]initializer_list模板类 C++primer 原文如下: 通读原文相关篇幅,分析解读内容如下: 提供initializer_list类的初衷,为了便于将有限个同一类型(或可转换为同 ...

  6. C++11模板类使用心得

    1.推荐使用std::shared_ptr<TaskT>代替指针TaskT*使用,shared_ptr是一种智能指针,能自主销毁释放内存,在c++11中被引入,在多线程编程中有很大的用处, ...

  7. c++模板类

    c++模板类 理解编译器的编译模板过程 如何组织编写模板程序 前言常遇到询问使用模板到底是否容易的问题,我的回答是:“模板的使用是容易的,但组织编写却不容易”.看看我们几乎每天都能遇到的模板类吧,如S ...

  8. C++ 模板函数与模板类

    一.模板函数 函数模板提供了一类函数的抽象,即代表了一类函数.当函数模板被实例化后,它会生成具体的模板函数.例如下面便是一个函数模板:

  9. 模板类重载<<运算符

    写了一个Matrix模板类,需要重载<<, 1.需要友元函数 2.需要此函数的实现在.h中(本人试验出来的,放在.cpp中编译不通过) template <typename T> ...

随机推荐

  1. 年度酷工作---高级数据工程师(公司靠谱,技术强悍,产品牛叉,福利有干货) 关键词:7000万用户、五星级厨师、住房补助 - V2EX

    年度酷工作---高级数据工程师(公司靠谱,技术强悍,产品牛叉,福利有干货) 关键词:7000万用户.五星级厨师.住房补助 - V2EX 年度酷工作---高级数据工程师(公司靠谱,技术强悍,产品牛叉,福 ...

  2. Android常用动画Animation的使用

    Andriod中有几种常用的Animation AlphaAnimation  淡入淡出效果 RotateAnimation 旋转效果 ScaleAnimation 缩放动画 TranslaAnima ...

  3. 中科燕园GIS外包---地铁GIS项目

    (1)地铁保护及project地质管理     • 地铁保护     地铁交通既有运量大,速度快的特点,又有差别于其它交通方式的在地下执行的空间特殊性,因此地铁的保护显得尤为重要. 首先必须编制完整的 ...

  4. 利用httpclient和多线程刷訪问量代码

    缘起于玩唱吧,由于唱吧好友少,訪问量低,又不想加什么亲友团之类的,主要是太麻烦了,于是我就琢磨唱吧的訪问机制,准备用java的httpclient库来进行刷訪问量,想到动态IP反复使用就想到了用多线程 ...

  5. ViewPager控件的Demo

    1.主视图 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:to ...

  6. BZOJ 2038: [2009国家集训队]小Z的袜子(hose) ( 莫队 )

    莫队..先按sqrt(n)分块, 然后按块的顺序对询问排序, 同块就按右端点排序. 然后就按排序后的顺序暴力求解即可. 时间复杂度O(n1.5) --------------------------- ...

  7. android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序

    android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序     在应用里使用了后台服务,并且在通知栏推送了消息,希望点击这个消息回到activity ...

  8. 黑龙江省第七届大学生程序设计竞赛-Mysterious Organization

    描述 GFW had intercepted billions of illegal links successfully. It has much more effect. Today, GFW i ...

  9. ZJOI2013 防守战线

    题目 战线可以看作一个长度为\(n\)的序列,现在需要在这个序列上建塔来防守敌兵,在序列第\(i\)号位置上建一座塔有\(C_i\)的花费,且一个位置可以建任意多的塔,费用累加计算.有\(m\)个区间 ...

  10. Linux笔记——linux下的语音合成系统

    1.festival 安装:sudo apt-get install festival 使用: (SayText "Hello!") 2. espeek(ubuntu 自带) # ...