您的位置:首页 > 编程语言 > C语言/C++

Exceptional C++, 实现一个不区分大小写的字符串比较类

2016-03-11 03:55 567 查看
C++标准库提供了字符串类
std::string
,这个类包含了字符串常用的操作,包括实现了
operator==
来实现字符串的比较,但这里的比较是区分大小写的。那么在不使用操作系统提供的不区分大小写函数的情况下,如何方便的利用
std::string
来实现一个区分大小写的类呢?这里的奥妙就在于巧妙地运用了
char_traits<char>
这个字符串的辅助模板类。

首先
std::string
的定义如下:

typedef basic_string<char, char_traits<char>, allocator<char>> string


typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring


所以我们可以以
char_traits<char>
(这里仅讨论窄字符串)为基类,重新定义其中相关的字符比较函数,其它的不变,从而可以方便的实现不区分大小写的字符串类。

struct ci_char_traits : public char_traits<char>
{
static bool eq( char c1, char c2 )
{
return toupper(c1) == toupper(c2);
}

static bool lt(char c1, char c2)
{
return toupper(c1) < toupper(c2);
}
static int compare( const char * s1,
const char * s2,
size_t n )
{
return memicmp(s1, s2, n);
}
static const char* find( const char* s, int n, char a )
{
while( n-- > 0 && toupper(*s) != toupper(a))
{
++s;
}
return n >= 0 ? s : 0;
}
};

typedef basic_string<char, ci_char_traits> ci_string;


以上实现比较讨巧,但不得不说虽然这样可以实现,但还是会有几个问题,如下:

1.
ci_char_traits
继承自
char_traits<char>
,但并不表示这两者之间是一种
is-a
关系,并且这两个类中的所有函数都是
static
的,所以两者间也不存在多态的这种关系。

2. 当
ci_string
string
去比较或者相加时会有问题,这个时候要么提供相应的比较或者相加函数,要么取两者的
.c_str()
来取得内部的字符串指针。

3. 利用
cout
来输出
std::string
是支持的,因为c++标准库里有这样的定义:

template<class char, class traits, class Allocator>
basic_ostream<char, traits>&
operator<<(basic_ostream<char, traits>& os,
const basic_string<char, traits, Allocator>& str)


cout
的类型则是
basic_ostream<char, char_traits<char> >
所以
cout
是无法输出ci_string类型的,当然有一种比较简单的输出方式是用输出
.c_str()
的方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: