Есть ли встроенная функция для преобразования строки C++ из прописных букв в строчные? Если не преобразовать его в cstring и использовать tolower для каждого символа, это единственный вариант?
Заранее большое спасибо.
Есть ли встроенная функция для преобразования строки C++ из прописных букв в строчные? Если не преобразовать его в cstring и использовать tolower для каждого символа, это единственный вариант?
Заранее большое спасибо.
Если 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
с учетом локали.
Как говорит ereOn: std::transform(str.begin(), str.end(), str.begin(), std::tolower );
Или через for_each: std::for_each(str.begin(), str.end(), std::tolower );
Преобразование, вероятно, лучше из двух.
Для этого нет встроенной функции, и сделать это на удивление сложно из-за локалей и др. Если tolower
делает то, что вам нужно, это может быть вашим лучшим выбором.
Для этой проблемы вы можете использовать метод преобразования STL для ее решения:
std::string str = "simple";
std::transform(str.begin(), str.end(), str.begin(), std::tolower);
У меня есть реализация, которую я нашел быстрее, чем std::transform , скомпилированная в g++ -03 Fedora 18. мой пример преобразует std::string
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;
}
Я буду рад узнать, можно ли еще улучшить производительность.
if (*p >= 'A' && *p <=Z) *p += 'a' - 'A'
. И вы по-прежнему потенциально пропускаете многие другие буквы, например. 'А'.
- person gatopeich; 13.04.2018
tolower
в <cctype>
и перегрузка в <locale>
. Если оба будут включены, вы получите ошибку компилятора. См., например: stackoverflow.com /вопросы/1350380/
- person UncleBens; 04.08.2010
transform
) потенциально могут вызвать неопределенное поведение, поскольку std::tolower
cstdlib
требует неотрицательного аргумента.
- person M.M; 16.08.2015
SS -> lowercase
; напримерSTRASSE -> straße
, ноTRASSE -> trasse
. Некоторые слова даже не однозначны:MASSE -> maße
(= меры, размеры) иMASSE -> masse
(= масса). (редактировать: только сейчас я понимаю, что уже посещал этот вопрос в прошлом, xd) - person Sebastian Mach   schedule 25.04.2012