本人写过与此相关的两篇博客,一个是<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
希望高手批评指正!!!
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。