我想转换一个std::字符串小写。我知道tolower()函数。然而,在过去,我有这个函数的问题,它几乎不是理想的无论如何使用std::string将需要迭代每个字符。

有没有一种替代方案能100%有效?


当前回答

改编自《不常见问题》:

#include <algorithm>
#include <cctype>
#include <string>

std::string data = "Abc";
std::transform(data.begin(), data.end(), data.begin(),
    [](unsigned char c){ return std::tolower(c); });

如果不遍历每个字符,你真的无法逃脱。否则就无法知道字符是小写还是大写。

如果你真的讨厌ower(),这里有一个专门的ascii替代方案,我不建议你使用:

char asciitolower(char in) {
    if (in <= 'Z' && in >= 'A')
        return in - ('Z' - 'z');
    return in;
}

std::transform(data.begin(), data.end(), data.begin(), asciitolower);

请注意,tolower()只能执行单个字节的字符替换,这不适用于许多脚本,特别是在使用UTF-8这样的多字节编码时。

其他回答

将字符串转换为小写而不用担心std名称空间的最简单方法如下

1:带/不带空格的字符串

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main(){
    string str;
    getline(cin,str);
//------------function to convert string into lowercase---------------
    transform(str.begin(), str.end(), str.begin(), ::tolower);
//--------------------------------------------------------------------
    cout<<str;
    return 0;
}

2:不带空格的字符串

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main(){
    string str;
    cin>>str;
//------------function to convert string into lowercase---------------
    transform(str.begin(), str.end(), str.begin(), ::tolower);
//--------------------------------------------------------------------
    cout<<str;
    return 0;
}

Boost为此提供了一个字符串算法:

#include <boost/algorithm/string.hpp>

std::string str = "HELLO, WORLD!";
boost::algorithm::to_lower(str); // modifies str

或者,对于非原位:

#include <boost/algorithm/string.hpp>

const std::string str = "HELLO, WORLD!";
const std::string lower_str = boost::algorithm::to_lower_copy(str);

我自己的模板函数,执行大写/小写。

#include <string>
#include <algorithm>

//
//  Lowercases string
//
template <typename T>
std::basic_string<T> lowercase(const std::basic_string<T>& s)
{
    std::basic_string<T> s2 = s;
    std::transform(s2.begin(), s2.end(), s2.begin(), tolower);
    return s2;
}

//
// Uppercases string
//
template <typename T>
std::basic_string<T> uppercase(const std::basic_string<T>& s)
{
    std::basic_string<T> s2 = s;
    std::transform(s2.begin(), s2.end(), s2.begin(), toupper);
    return s2;
}

因为你正在使用std::string,你正在使用c++。如果使用c++11或更高版本,则不需要任何花哨的东西。如果words是vector<string>,那么:

    for (auto & str : words) {
        for(auto & ch : str)
            ch = tolower(ch);
    }

没有奇怪的异常。可能想要使用w_char's,但除此之外,这应该全部到位。

如果你想要一些简单的东西,这里有一个宏观的技巧:

#define STRTOLOWER(x) std::transform (x.begin(), x.end(), x.begin(), ::tolower)
#define STRTOUPPER(x) std::transform (x.begin(), x.end(), x.begin(), ::toupper)
#define STRTOUCFIRST(x) std::transform (x.begin(), x.begin()+1, x.begin(),  ::toupper); std::transform (x.begin()+1, x.end(),   x.begin()+1,::tolower)

但是,请注意,如果您正在处理的不仅仅是ASCII字符,那么@AndreasSpindler对这个答案的评论仍然是一个重要的考虑因素。