Код не возвращает правильный символ в cpp

Вопрос: Первая заглавная буква в строке (рекурсивная) Сомневаться:, почему этот код не возвращает правильный символ, даже если он входит в предложение if в правильное время (когда буква в верхнем регистре). Я добавил эти операторы cout только для целей отладки.

# include <bits/stdc++.h>
using namespace std;
char UpperCase(string str, int i){
    
    cout<<" str "<<i<<" "<<str[i]<<endl;
    if (i==str.length()){
        return '0';
    }
    if (str[i]>=65 && str[i]<=90 ){
        char r=str[i];
        cout<<" r "<<i<<" "<<r<<endl;
        return r;
    }
    
    UpperCase(str, i+1);
}
int main(){
string str;
char r;
cout<<"Enter string : ";
cin>>str;
 r=UpperCase(str,0);
 cout<<r<<endl;
 return 0;
}

выход

Enter no of element : geeksforgeeKs
 str 0 g
 str 1 e
 str 2 e
 str 3 k
 str 4 s
 str 5 f
 str 6 o
 str 7 r
 str 8 g
 str 9 e
 str 10 e
 str 11 K
 r 11 K
ö

Ожидал

K (instead of ö)

Наиболее актуально для вашего вопроса, что делает возврат в все достижимых путях кода (смотря на ты, неполученный результат возврата из рекурсивного вызова UpperCase). Включите предупреждения вашего компилятора и относитесь к ним как к ошибкам.

WhozCraig 18.03.2022 18:59

Почему вы выбрали рекурсивный подход? Цикл был бы проще и не сожрал бы стек.

lurker 18.03.2022 19:12

@lurker да! это легко из циклов, но на самом деле я изучаю рекурсию.

Kiran 19.03.2022 06:59

Как было указано в ответе, лучше не использовать «магические числа». Существует стандартный макрос, который вы можете использовать для проверки верхнего регистра: используйте isupper(str[i]) вместо str[i]>=65 && str[i]<=90.

lurker 19.03.2022 12:55
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
29
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я предполагаю, что это академическое упражнение. Никто на самом деле реализовал бы эту задачу с помощью рекурсии (и они не использовали бы магические числа, чума, известная как <bits/stdc++.h>, практику ужасный, распространенную на мусорных «конкурентных» сайтах программирования и т. д.)

Тем не менее, распространенная ошибка очень, совершаемая студентами при изучении рекурсии, заключается в том, что они не понимают, что функция, передающая свои результаты с помощью возвращаемого значения, должна быть извлечена из рекурсивного вызова. Вы стали жертвой этой ошибки здесь.

Удаление операторов отладки и просмотр самого кода:

char UpperCase(string str, int i)
{
    if (i == str.length())
    {
        return '0';
    }
    if (str[i] >= 65 && str[i] <= 90)
    {
        return str[i];
    }

    UpperCase(str, i + 1); // <===== HERE
}

Обратите внимание, что UpperCase возвращает char (или, по крайней мере, утверждает). Но в рекурсивном случае вы не пожинаете этот результат. На самом деле вы не возвращаете что-либо. Это не только логическая ошибка, она также приводит к неопределенное поведение. Любой, кто вызывает эту функцию, чтобы пожинать ее результат, и если нет попадает в одно из двух других целевых условий выхода немедленно, не будет иметь определенного результата. Ваш компилятор скажет вам это, если вы обратите внимание на его предупреждения:

warning: control reaches end of non-void function [-Wreturn-type]

Самый простой способ решить эту проблему — вспомнить, что должна возвращать ваша функция, а затем убедиться, что она возвращает это.

char UpperCase(string str, int i)
{
    if (i == str.length())
    {
        return '0';
    }
    if (str[i] >= 65 && str[i] <= 90)
    {
        return str[i];
    }

    return UpperCase(str, i + 1); // <===== FIXED
}

Другие вопросы по теме