是否可以使std :: string始终保持小写字符串?

时间:2013-01-31 12:06:30

标签: c++ string boost stl

是否可以使std :: string始终保持小写字符串? 这是我将如何使用它:

typedef std::basic_string<...> lowercase_string;

void myfunc()
{
  lowercase_string s = "Hello World"; // notice mixed case
  printf(s.c_str());                  // prints "hello world" in lowercase
  std::string s2 = s;
  printf(s2.c_str());                 // prints "hello world" in lowercase
}

3 个答案:

答案 0 :(得分:18)

您可以编写自己的char特征并将其作为第二个模板参数传递给std::basic_string

以下是 minimal 示例:

template<typename T>
struct lowercase_char_traits : std::char_traits<T>
{
    static T* copy(T* dest, const T* src, std::size_t count )
    {
         for(size_t i = 0 ; i < count ; ++i)
              dest[i] = std::tolower(src[i]);
         return dest;
    }
    static void assign(T & out, T in)
    {
       out = std::tolower(in);
    }
    //implement other overload of assign yourself

    //note that you may have to implement other functionality 
    //depending on your requirement
};

然后将typedef定义为:

typedef std::basic_string<char, lowercase_char_traits<char>> lowercase;

这是一个测试程序:

int main() 
{
    lowercase s1 = "Hello World";
    std::cout << s1.c_str() << std::endl;

    lowercase s2 = "HELLO WORLD";
    std::cout << std::boolalpha << (s1 == s2) << std::endl;

    lowercase s3 = "HELLO";
    s3 += " WorL";
    s3.append("D");
    std::cout << std::boolalpha << (s1 == s3) << std::endl;

    std::cout << s2.c_str() << std::endl;
    std::cout << s3.c_str() << std::endl;
}

输出:

hello world
true
true
hello world
hello world

很酷,不是吗?


请注意,要拥有一个完全工作的小写字符串类,可能还需要定义lowercase_char_traits的其他功能,具体取决于您希望从此类中获取的行为。

详细了解Herb Sutter精彩文章:

希望有所帮助。

答案 1 :(得分:2)

您可以使用私有继承。这将使您免于编写一堆包装器方法。

class lower_case_string : private std::string
{
    // define constructors that do the conversion to lower case
    // ...

    // expose functionality from std::string
    using std::string::size;
    using std::string::length;
    using std::string::cbegin;
    // etc.

    // Make sure NOT to expose methods that allow modification as they
    // could violate your invariant that all characters are lower case.
    // E.g., don't expose std::string::begin, instead write your own.
};

答案 2 :(得分:0)

你必须在类的周围创建一个包装器(正如Chad在评论中提到的更好地使用组合),它将每个字符转换为其构造函数中的较低版本。不幸的是,std::string无法开箱即用。或者创建自己的函数来打印字符串,或者在打印之前将字符串转换为小写字母。