Как преобразовать экземпляр std::string в нижний регистр
Я хочу преобразовать stdstring
в нижний регистр. Я знаком с функцией tolower()
. Однако у меня в прошлом возникали проблемы с этой функцией, и, кроме того, это не самый идеальный вариант, поскольку использование tolower()
с stdstring
требует итерации по каждому символу.
Существует ли альтернатива, которая будет работать на 100%?
5 ответ(ов)
Ваш код действительно выглядит намного проще благодаря использованию цикла for
на основе диапазона, введенного в C++11. В вашем примере вы обрабатываете строку str
и преобразуете каждый символ к нижнему регистру с помощью функции std::tolower
, что делает код более читаемым и лаконичным.
Предлагаемый вами код:
#include <iostream> // std::cout
#include <string> // std::string
#include <locale> // std::locale, std::tolower
int main ()
{
std::locale loc;
std::string str="Test String.\n";
for(auto elem : str)
std::cout << std::tolower(elem, loc);
}
использует auto
для определения типа elem
, что делает код более гибким. Это позволяет избежать необходимости явного указания типа элемента, что особенно полезно, когда вы работаете с контейнерами или другими структурами данных.
Не забудьте, что если вашей целью является отображение строки в нижнем регистре, а не просто вывод каждого символа, вы можете также сохранить результат в новую строку и вывести её после завершения цикла. Например:
#include <iostream>
#include <string>
#include <locale>
int main ()
{
std::locale loc;
std::string str = "Test String.\n";
std::string result;
for (auto elem : str)
result += std::tolower(elem, loc);
std::cout << result;
}
Таким образом, вы сохраняете преобразованную строку и выводите её в конце, что может быть более эффективно, если строка будет использоваться позже.
Вы можете использовать диапазонный цикл for с ссылочной переменной для изменения символов в строке на строчные. Вот пример кода:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string test = "Hello World";
for(auto& c : test) {
c = tolower(c); // Применяем tolower к каждому символу строки
}
cout << test << endl; // Выводим изменённую строку
return 0;
}
В этом коде мы используем auto& c
, чтобы получить ссылку на каждый символ в строке test
. Это позволяет изменять символы непосредственно в строке без создания дополнительных копий. Функция tolower
преобразует каждый символ в строчный регистр. В результате на выходе мы получаем строку "hello world".
Если строка содержит символы UTF-8, которые выходят за пределы ASCII, то boost::algorithm::to_lower
не выполнит их преобразование в нижний регистр. Рекомендуется использовать boost::locale::to_lower
, когда вы работаете с UTF-8. Дополнительную информацию можно найти по ссылке: Boost.Locale.
В ответ на ваш вопрос: если вы хотите разместить результат преобразования в другой строке, вам необходимо заранее выделить для неё пространство, прежде чем вызывать std::transform
. Поскольку STL сохраняет преобразованные символы в заданном итераторе назначения (увеличивая его на каждой итерации цикла), строка назначения не будет автоматически изменять свой размер, и это может привести к переполнению памяти.
Вот пример кода, демонстрирующий это:
#include <string>
#include <algorithm>
#include <iostream>
int main (int argc, char* argv[])
{
std::string sourceString = "Abc";
std::string destinationString;
// Выделяем пространство для строки назначения
destinationString.resize(sourceString.size());
// Преобразуем исходную строку в нижний регистр
// и сохраняем результат в строку назначения
std::transform(sourceString.begin(),
sourceString.end(),
destinationString.begin(),
::tolower);
// Выводим результат преобразования
std::cout << sourceString
<< " -> "
<< destinationString
<< std::endl;
}
Таким образом, убедитесь, что вы выделили достаточно места для строкового результата, чтобы избежать потенциальных проблем с памятью.
Самый простой способ преобразовать строку в нижний регистр, не беспокоясь о пространстве имен std, следующий:
- Для строки с/без пробелов:
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main() {
string str;
getline(cin, str);
//------------ функция для преобразования строки в нижний регистр ---------------
transform(str.begin(), str.end(), str.begin(), ::tolower);
//--------------------------------------------------------------------
cout << str;
return 0;
}
- Для строки без пробелов:
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main() {
string str;
cin >> str;
//------------ функция для преобразования строки в нижний регистр ---------------
transform(str.begin(), str.end(), str.begin(), ::tolower);
//--------------------------------------------------------------------
cout << str;
return 0;
}
В обоих случаях используется функция transform
из библиотеки <algorithm>
, которая принимает диапазон элементов и применяет к ним указанную функцию (в данном случае tolower
). Это позволяет легко и эффективно конвертировать строку в нижний регистр.
В чем проблема с "using namespace std;"?
Как перебрать слова в строке?
Как преобразовать int в строку в C++?
Как преобразовать std::string в const char* или char*
`std::wstring` против `std::string`: когда использовать и в чем разница?