Как преобразовать все алфавиты в верхний регистр, используя преобразование, игнорирующее цифры?

Мне нужно преобразовать только буквы в строке в верхний регистр, и я попробовал этот фрагмент кода, который выдает ошибку.

   s = "Dense-123-Sparse-999" 
   std::transform(s.begin(), s.end(), s.begin(), std::toupper);

Ожидаемый результат: DENSE-123-SPARSE-999.

Ошибка: непустая лямбда не возвращает значение во всех путях управления [-Werror,-Wreturn-type]

Выдает ошибку, так как во входной строке есть цифры. Как написать лямбда-функцию, которая преобразует символы в верхний регистр, только если они являются алфавитом, а не числом?

что-то вроде этого,

transform_if(s.begin(), s.end(), s.begin, [](char c){ if(isalpha(c)return toupper(c);});

так как C++ не имеет transform_if, я ищу один лайнер с любыми другими командами.


person ElevenCents    schedule 10.12.2020    source источник
comment
Имейте в виду, что в 2020 году у нас UTF-8 везде, поэтому рассмотрите возможность использования таких библиотек, как Qt или POCO. Как бы вы поступили со знаком é или à или или ° или §? Все они есть на моей AZERTY клавиатуре...   -  person Basile Starynkevitch    schedule 10.12.2020
comment
Однако прочтите какую-нибудь хорошую книгу по программированию на C++ и см. эта ссылка на C++   -  person Basile Starynkevitch    schedule 10.12.2020


Ответы (2)


используйте лямбда или функцию

char upperize(char c)
{
    return toupper(c);
}
transform(s.begin(),s.end(),s.begin(),upperize);
 
transform(s.begin(),s.end(),s.begin(),[](char s){return toupper(s);});
cout<<s;

вы можете использовать isalpha также в дополнение

person pranjal khatri    schedule 10.12.2020
comment
Не работает ни для Être ou ne pas être, ни для твоего имени на хинди, ни для моего имени на русском (СТАРЫНКЕВИЧ) - person Basile Starynkevitch; 10.12.2020
comment
@BasileStarynkevitch, который обсуждался [здесь](stackoverflow.com/questions/36897781/ - person pranjal khatri; 10.12.2020

Отвечая на мой собственный вопрос, выяснил transform и for_each с кодом lambda. работает для букв без ударения.

for_each(s.begin(), s.end(), [](char &c) { c = (isalpha(c))? toupper(c):c; } ) ;

or

transform(s.begin(), s.end(), s.begin(), [](char &c) { return (isalpha(c))?toupper(c):c ; });

Благодаря комментариям Basile, которые познакомили нас с UTF-8, мой код не удался для следующего случая:

input: "èéêrię"

output: "èéêRIę" (wrong)

нужно будет вернуться и найти использование библиотеки UTF-8

person ElevenCents    schedule 10.12.2020
comment
См. также лямбда-выражения с [](unsigned char c) { return std::toupper(c); } - person David C. Rankin; 10.12.2020
comment
так как у вас есть две точки с запятой, я думаю, что это не считается одним вкладышем - person Patrick Parker; 10.12.2020