本人写过与此相关的两篇博客,一个是<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. Week3(9月23日):例子更Powerful更完整了,哇咔咔

    Part I:提问  =========================== 1.控制器中动作方法的返回类型有哪些? 2.如果控制器代码如下,请问浏览器中如何输入什么路由访问? public clas ...

  2. MVC 扩展 Html.ImageFor

    Asp.Net MVC 扩展 Html.ImageFor 方法详解 背景: 在Asp.net MVC中定义模型的时候,DataType有DataType.ImageUrl这个类型,但htmlhelpe ...

  3. 如何使用银联卡充值美元到BTC-E以及比特币搬砖教程

    1,名词解释 搬砖:就是在价格低的平台买入比特币,然后转移到价格高的平台卖出, 一般而言,BTC-E是国外三大比特币交易所中比特币单价最低的一个站,因为其需要用美元充值,相对不方便.之前国内比特币价格 ...

  4. csharp .net vb 复制图像

    .NET Compact Framework 不支持 Image.Clone 方法,可是仍能够复制图像和图像的某些部分.以下的演示例子演示怎样运行以下操作: 定义一个方法以创建位图. 定义一个重载方法 ...

  5. vim-ctags-taglist-netrw

    vim配置 在~/.vimrc文件里配置例如以下内容.或者在/etc/vim/vimrc中进行全局配置,经常使用配置例如以下: syntax on set tabstop=4 set nu set s ...

  6. cygrunsrv: Error starting a service: QueryServiceStatus: Win32 error 1062: 解决办法

    问题原因:很可能是/var/log的权限设置不正确.首先执行 mkpasswd 和 mkgroup 重新生成权限信息,再删除sshd服务,重新配置 解决办法: $ mkpasswd -l > / ...

  7. 关于apche无缘无故个启动不了,解决方法

    1. 对于用户不小心把apache下的conf文件不小心给修改了,可那会导致,启动不了apache, 解决办法可以重新下载一个, 64为  32位  下载地址 http://www.veryhuo.c ...

  8. SQL查询重复记录、删除重复记录方法

    查找所有重复标题的记录:SELECT * FROM t_info a WHERE ((SELECT COUNT(*) FROM t_info WHERE Title = a.Title) > 1 ...

  9. 网页制作之html基础学习5-background-position用法

    我们知道在用图片作为背景的时候,css要这样写,以div容器举例子,也可以是body.td.p等的背景,道理一样. 代码: div{ background:#FFF url(image) no-rep ...

  10. 树莓派linux驱动学习之hello world

    最近想学习一下linux驱动,看了一些书和教学视频,大概了解了一下,不过要想深入,肯定需要实践.手上有几块linux的板子,最终选择了树莓派作为我的实验平台,资料比较丰富,接口也比较简单. 程序员的入 ...