美文网首页Exceptional C++
【Exceptional C++(2)】不区分大小写的strin

【Exceptional C++(2)】不区分大小写的strin

作者: downdemo | 来源:发表于2018-01-26 13:06 被阅读24次

问题

  • 写一个不分大小写的字符串比较类,std::string提供了operator==实现比较,但是区分大小写。我们希望达到下面的目标
ci_string s("AbCdE");
assert(s == "abcde");
assert(s == "ABCDE");
assert(strcmp(s.c_str(), "AbCdE") == 0); // c_str()返回C字符串指针,const char* c_str()
assert(strcmp(s.c_str(), "abcde") != 0);

解答

  • string头文件中可以看到
typedef basic_string<char> string;
  • 所以string并不是一个真正的类,只是一个特化的typedef,再看basic_string<>模板声明
template<class charT,
    class traits = char_traits<charT>,
    class Allocator<charT> >
class basic_string;
  • 所以string实际上是basic_string<char, char_traits<char>, allocator<char> >,先不关心allocator部分,关键的是char_traits部分,决定了字符的相互作用和比较运算。basic_string提供了常用的比较函数比较两个string对象是否相等或一个小于另一个。具体来说,char_traits模板提供了这些字符比较函数:eq() 相等, ne() 不等, lt() 小于, compare() 比较字符序列, find() 搜索字符序列。如果希望在string的这些操作上有不同行为,只需要提供一个不同的char_traits模板
struct ci_char_traits : public char_traits<char>
{
    static bool eq( char c1, char c2 )
    {
        return toupper(c1) == toupper(c2);
    }
    static bool ne( 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;
  • 我们根本没碰basic_string就实现了不区分大小写的string,这揭示了basic_string模板的工作原理和实现使用上的灵活性,如果你不想用memicmp()和toupper(),可以用自己的代码替换这些比较函数
  • ci_char_traits继承自char_traits<char>,但并非is-a关系,且两个类中所有函数都是static,也不存在多态
  • 如果混用ci_string和string,比如相加,要定义ci_string自己的这些操作,或者取两者的.c_str()
  • cout可以输出string,但不能输出ci_string
template<class char, class traits, class Allocator>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os,
    const basic_string<charT, traits, Allocator>& str)
  • 要输出ci_string,需要自己定义操作,或者直接使用.c_str()
ci_string s = "abc";
cout << s.c_str() << endl;

相关文章

  • 【Exceptional C++(2)】不区分大小写的strin

    问题 写一个不分大小写的字符串比较类,std::string提供了operator==实现比较,但是区分大小写。我...

  • 04 php变量、常量

    1.区分大小写 php变量区分大小写,php常量也区分大小写,可以设置为不区分,不建议,而系统关键字不区分。 2....

  • 2020-03-11 c++ book

    exceptional c++ style 中文版more exceptional c++ 中文版exceptio...

  • 一.预备知识

    C++对大小写敏感,也就是区分大小写。 C++必须包含一个名为main()的函数。 C++注释以 // 开头。 如...

  • PHP基本语法形式

    PHP的区分大小写特性 1:变量区分大小写(通常小写)。 2:常量通常默认也区分,但可以设定为不区分(通常大写)。...

  • nginx(二):符号语句

    一.正则表达式匹配,其中: ~ 为区分大小写匹配 ~* 为不区分大小写匹配 !和!*分别为区分大小写不匹配及不区分...

  • PHP大小写

    PHP变量区分大小写,函数名不区分大小写。

  • 修改github区分大小写 -- 删除远程分支文件

    window for git客户端默认是不区分大小写 ps:代码在window不区分大小写在linux会区分大小写...

  • Nginx 转发匹配规则,后端程序员必备知识点

    一、正则表达式匹配 ~ 为区分大小写匹配 ~* 为不区分大小写匹配 !~ 和 !~* 分别为区分大小写不匹配及不区...

  • Nginx配置文件nginx.conf详解

    一.正则表达式匹配,其中: ~ 为区分大小写匹配~* 为不区分大小写匹配!~ 和!~*分别为区分大小写不匹配及不区...

网友评论

    本文标题:【Exceptional C++(2)】不区分大小写的strin

    本文链接:https://www.haomeiwen.com/subject/euwiaxtx.html