2010-08-04 1 views
13

Есть ли встроенная функция для преобразования строки C++ из строчных букв в строчные буквы? Если не преобразовать его в cstring и использовать tolower на каждом символе, это единственный вариант?функция tolower для строк C++

спасибо, что заранее.

+4

В Германии, tolower («STRASSE»), должно получиться «straße». В Швейцарии это должно быть «strasse». И таких случаев гораздо больше, чем во всем мире. Встроенная функция должна правильно обрабатывать эти случаи. Если вам все равно, просто используйте tolower() для каждого символа, как показывает большинство ответов. – Sjoerd

+0

@Sjoerd: Хороший пример. Вы слышали о какой-либо библиотеке, которая имеет дело с этими случаями изящно? Меня это могло заинтересовать. – ereOn

+0

@ereOn: Нет, мне он никогда не нужен. Я знаю, что есть проблемы с tolower(), но где я живу, и в приложениях, которые я пишу, tolower() обычно «достаточно хорош». – Sjoerd

ответ

24

Если boost вариант:

#include <boost/algorithm/string.hpp>  

std::string str = "wHatEver"; 
boost::to_lower(str); 

В противном случае, вы можете использовать std::transform:

std::string str = "wHatEver"; 
std::transform(str.begin(), str.end(), str.begin(), ::tolower); 

Вы можете также использовать другую функцию, если у вас есть некоторые пользовательские локали осведомленный tolower.

1

Для этого нет встроенной функции, и сделать это на удивление сложно, из-за локалей и др. Если tolower делает то, что вам нужно, это может быть вашим лучшим выбором.

11
std::transform(myString.begin(), myString.end(), myString.begin(), std::tolower); 
+5

В этом и других ответах transform + tolower следует учитывать, что это не обязательно будет компилироваться, в зависимости от того, какие стандартные заголовки включены в этот файл.В '' есть один' tolower' и перегрузка в ''. Если оба включены, вы получите ошибку компилятора. См. Например: http://stackoverflow.com/questions/1350380/problems-using-stl-stdtransform-from-cygwin-g – UncleBens

+0

Обратите внимание, что этот ответ (и все другие ответы 'transform') потенциально может привести к неопределенному поведению, потому что 'std :: tolower' cstdlib' требует неотрицательного аргумента –

2

Как ereOn говорит: std::transform(str.begin(), str.end(), str.begin(), std::tolower);

Или через for_each: std::for_each(str.begin(), str.end(), std::tolower);

Transform, вероятно, лучше двух.

+2

Уверен, что так. for_each не изменяет str. –

+0

Это было записано с манжетой. Вы можете использовать lamda для вызова tolower для каждого символа. –

0

Для этой задачи вы можете использовать STL в метод преобразования, чтобы решить:

std::string str = "simple"; 
std::transform(str.begin(), str.end(), str.begin(), std::tolower); 
0

Я реализация Я нашел его быстрее, чем станд :: трансформируют, Составитель в г ++ -03 Fedora 18. мой пример новообращенные станд :: строка

 
performance time in seconds : 
transform took   : 11 s 
my implementation took : 2 s 
Test data size = 26*15*9999999 chars 
inline void tolowerPtr(char *p) ; 

inline void tolowerStr(std::string& s) 
{char* c=const_cast<char*>(s.c_str()); 
size_t l = s.size(); 
    for(char* c2=c;c2<c+l;c2++)tolowerPtr(c2); 
}; 

inline void tolowerPtr(char *p) 
{ 
switch(*p) 
{ 
    case 'A':*p='a'; return; 
    case 'B':*p='b'; return; 
    case 'C':*p='c'; return; 
    case 'D':*p='d'; return; 
    case 'E':*p='e'; return; 
    case 'F':*p='f'; return; 
    case 'G':*p='g'; return; 
    case 'H':*p='h'; return; 
    case 'I':*p='i'; return; 
    case 'J':*p='j'; return; 
    case 'K':*p='k'; return; 
    case 'L':*p='l'; return; 
    case 'M':*p='m'; return; 
    case 'N':*p='n'; return; 
    case 'O':*p='o'; return; 
    case 'P':*p='p'; return; 
    case 'Q':*p='q'; return; 
    case 'R':*p='r'; return; 
    case 'S':*p='s'; return; 
    case 'T':*p='t'; return; 
    case 'U':*p='u'; return; 
    case 'V':*p='v'; return; 
    case 'W':*p='w'; return; 
    case 'X':*p='x'; return; 
    case 'Y':*p='y'; return; 
    case 'Z':*p='z'; return; 
}; 
return ; 
} 

void testtransform(std::string& word) 
{ 
std::string word2=word; 
time_t t; 
time_t t2; 
time(&t); 
std::cout << "testtransform: start " << "\n"; 
int i=0; 
for(;i<9999999;i++) 
{ word2=word; 
    std::transform(word2.begin(), word2.end(), word2.begin(), ::tolower); 
} 
time(&t2); 
std::cout << word2 << "\n"; 
std::cout << "testtransform: end " << i << ":"<< t2-t << "\n"; 
} 

void testmytolower(std::string& word) 
{ 
std::string word2=word; 
time_t t; 
time_t t2; 
time(&t); 
std::cout << "testmytolower: start " << "\n"; 
int i=0; 
for(;i<9999999;i++) 
{ word2=word; 
    cstralgo::tolowerStr(word2); 
} 
time(&t2); 
std::cout << word2 << "\n"; 
std::cout << "testmytolower: end " << i << ":"<< t2-t << "\n"; 
} 

int main(int argc, char* argv[]) 
{ 
    std::string word ="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    word =word+word+word+word+word+word+word+word+word+word+word+word+word+word+word; 
    testtransform(word); 
    testmytolower(word); 
    return 0; 
} 

Я буду рад узнать, если производительность может быть улучшена дополнительно.