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

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


当前回答

我写了这个简单的helper函数:

#include <locale> // tolower

string to_lower(string s) {        
    for(char &c : s)
        c = tolower(c);
    return s;
}

用法:

string s = "TEST";
cout << to_lower("HELLO WORLD"); // output: "hello word"
cout << to_lower(s); // won't change the original variable.

其他回答

我写了这个简单的helper函数:

#include <locale> // tolower

string to_lower(string s) {        
    for(char &c : s)
        c = tolower(c);
    return s;
}

用法:

string s = "TEST";
cout << to_lower("HELLO WORLD"); // output: "hello word"
cout << to_lower(s); // won't change the original variable.

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);

有一种方法可以在不进行if测试的情况下将大写字母转换为小写字母,而且非常简单。isupper()函数/宏对clocale.h的使用应该可以解决与您的位置相关的问题,但如果没有,您可以随时根据自己的需要调整UtoL[]。

假设C语言的字符实际上只是8位整型(暂时忽略宽字符集),您可以创建一个256字节的数组,保存另一组字符,并在转换函数中使用字符串中的字符作为转换数组的下标。

但是,不是1对1的映射,而是为小写字符赋予大写数组成员BYTE int值。你可能会发现islower()和isupper()在这里很有用。

代码看起来是这样的……

#include <clocale>
static char UtoL[256];
// ----------------------------------------------------------------------------
void InitUtoLMap()  {
    for (int i = 0; i < sizeof(UtoL); i++)  {
        if (isupper(i)) {
            UtoL[i] = (char)(i + 32);
        }   else    {
            UtoL[i] = i;
        }
    }
}
// ----------------------------------------------------------------------------
char *LowerStr(char *szMyStr) {
    char *p = szMyStr;
    // do conversion in-place so as not to require a destination buffer
    while (*p) {        // szMyStr must be null-terminated
        *p = UtoL[*p];  
        p++;
    }
    return szMyStr;
}
// ----------------------------------------------------------------------------
int main() {
    time_t start;
    char *Lowered, Upper[128];
    InitUtoLMap();
    strcpy(Upper, "Every GOOD boy does FINE!");

    Lowered = LowerStr(Upper);
    return 0;
}

与此同时,这种方法允许您重新映射希望更改的任何其他字符。

当在现代处理器上运行时,这种方法有一个巨大的优势,不需要做分支预测,因为没有包含分支的if测试。这为其他循环节省了CPU的分支预测逻辑,并倾向于防止管道停顿。

这里的一些人可能认识到这种方法与将EBCDIC转换为ASCII时使用的方法相同。

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

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

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

使用此代码在c++中更改字符串的大小写。

#include<bits/stdc++.h>

using namespace std;

int main(){
  string a = "sssAAAAAAaaaaDas";
  transform(a.begin(),a.end(),a.begin(),::tolower);
  cout<<a;
}