-3

Using the C++ language, the function LetterChanges(str) takes the str parameter being passed and modifies it using the following algorithm.

Replace every letter in the string with the letter following it in the alphabet (ie. c becomes d, z becomes a). Then capitalize every vowel in this new string (a, e, i, o, u) and finally return this modified string.

#include <iostream>
using namespace std;

string LetterChanges(string str) {

    // code goes here
    string str2 = "abcdefghijklmnopqrstuvwxyz";
    int j;
    for (int i = 0; str[i] != '\0'; i++) {

        for (j = 0; str2[j] != '\0'; j++) {

            if (str[i] == str2[j]) {

                str[i] = str2[j + 1];

            }
        }
    }
    for (int i = 0; str[i] != '\0'; i++) {
        if (str[i] == 'a') {
            str[i] = 'A';
        }
        else if (str[i] == 'e') {
            str[i] = 'E';
        }
        else if (str[i] == 'i') {
            str[i] = 'I';
        }
        else if (str[i] == 'o') {
            str[i] = 'O';
        }
        else if (str[i] == 'u') {
            str[i] = 'U';
        }
    }
    return str;
}
int main() {
    // keep this function call here
    cout << LetterChanges(gets(stdin));
    return 0;
}

I am trying to run this code but it is not giving the desire output please help..

scohe001
  • 15,110
  • 2
  • 31
  • 51
  • 7
    It sounds like you may need to learn how to use a debugger to step through your code. With a good debugger, you can execute your program line by line and see where it is deviating from what you expect. This is an essential tool if you are going to do any programming. Further reading: [How to debug small programs](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – NathanOliver Aug 07 '17 at 15:45
  • In the First two For loops i am trying to copy alphabets and in the next for loop trying to uppercase lowercase vowels. – kunal suryawanshi Aug 07 '17 at 15:47
  • the function `string LetterChanges(string str)` has no chance to modify the string that is passed to it (only a copy of it). Maybe change it to `string LetterChanges(string& str)` ? – 463035818_is_not_an_ai Aug 07 '17 at 15:48
  • and also How to make case for z to convert it to a?? – kunal suryawanshi Aug 07 '17 at 15:49
  • How does this code not flag a monster warning/error about pointer incompatibility when invoking [`gets`](http://en.cppreference.com/w/cpp/io/c/gets) ([which you should never use](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used)) with a `FILE*` rather than a `char*` ? – WhozCraig Aug 07 '17 at 15:50
  • i am not getting your point can you please elaborate?? – kunal suryawanshi Aug 07 '17 at 15:50
  • can you please talk to some basics all your comments going up from my mind – kunal suryawanshi Aug 07 '17 at 15:52
  • go to the closest pharmacy and get a [rubber_duck](https://en.wikipedia.org/wiki/Rubber_duck_debugging) – ΦXocę 웃 Пepeúpa ツ Aug 07 '17 at 15:53
  • 1
    [Read the link I posted to concerning `gets`](http://en.cppreference.com/w/cpp/io/c/gets). Besides the most important part (you shouldn't be using it *at all*), you're not using it correctly. You're passing a `FILE*` (stdin) rather than a `char*` as its argument. This code should't even *compile*, much less run to an error. If it compiles, I have zero-respect for whatever C++ toolchain you're using. – WhozCraig Aug 07 '17 at 15:55
  • its an online platform for coding CoderByte – kunal suryawanshi Aug 07 '17 at 16:01
  • @kunal Rather use `std::getline()` to read the input. What you have is completely nonsensical. – user0042 Aug 07 '17 at 16:03
  • Does a c++ string need to be terminated with a null character? Should you be using iterators? `using namespace std ` is bad - Google that.why are you using `stdio`? Perhaps read up on const – Ed Heal Aug 07 '17 at 16:11
  • @AlexG yeah. Should have read the whole question before giving unqualified comments ;) – 463035818_is_not_an_ai Aug 07 '17 at 17:03

1 Answers1

2

The Function

Let's start with your first loop:

for (int i = 0; str[i] != '\0'; i++) {
    for (j = 0; str2[j] != '\0'; j++) {
        if (str[i] == str2[j]) {
            str[i] = str2[j + 1];
        }
    }
}

There are a couple things here. Firstly, we don't even need to deal with str2. Characters in C++ use ASCII encoding, meaning we can actually do something like str[i]++ to change an 'a' to a 'b' or an 'e' to an 'f', etc...

Also, I'd advise against using str[i] != '\0'. We're using the standard library strings instead of c-strings for a reason, so we might as well make our lives easier and use str.size(). Along these same lines, I'd suggest str.at(i) as opposed to str[i] as the former will do bounds checking for us.

Lastly, if you include cctype, then we can use the isalpha function to make sure we're only modifying alphabetic characters (no numbers or spaces, etc..).

Thus your first loop can become:

for (int i = 0; i < str.size(); i++) {
    if(isalpha(str.at(i)){
        if(str.at(i) == 'z') str.at(i) = 'a'; //special case
        else str.at(i)++;
    }
}

As far as your second loop, you don't even need it! We can actually incorporate everything straight into the first one. As long as we make sure to do the vowel modification after we've changed the individual letters.

A conversion from lowercase to uppercase can be done with some ASCII math as well. The difference between the lowercase and uppercase letters is 'A'-'a', so if we add that to any lowercase letter, it'll give us its uppercase version!

With all of this, we can modify your code to:

for (int i = 0; i < str.size(); i++) {
    if(isalpha(str.at(i)){ //Make sure it's a letter!
        if(str.at(i) == 'z') str.at(i) = 'a'; //special case
        else str.at(i)++;

        if(str.at(i) == 'a' | str.at(i) == 'e' | str.at(i) == 'i' 
           | str.at(i) == 'o' | str.at(i) == 'u') {
           str.at(i) += 'A' - 'a'; 
    }
}

Your Main

There's only one thing to fix here. Don't use gets for input. If you're looking for a single word, use the extraction operator, >>, or if you want a whole line, use getline.

string word, line;

getline(cin, line);
cin >> word;

cout << LetterChanges(line) << endl;
cout << LetterChanges(word) << endl;
scohe001
  • 15,110
  • 2
  • 31
  • 51
  • Thankyou so much understood the code and many more things also thankyou you are a genius – kunal suryawanshi Aug 07 '17 at 16:10
  • can you please explain this line str.at(i) += 'A' - 'a'; – kunal suryawanshi Aug 07 '17 at 16:28
  • @kunalsuryawanshi Take a look at the [ASCII table](http://www.asciitable.com/). The difference between any lowercase/uppercase pair is the same. That is, the distance from 'b' to 'B' is the same as 'f' to 'F', etc... So if we add that difference (I chose to use a's to calculate it), namely, `'A'-'a'` to any lowercase letter, it will become an uppercase letter. If you don't believe me, try the math with the table yourself! – scohe001 Aug 07 '17 at 16:30
  • @scohe001 What about the `gets()` issue? – user0042 Aug 07 '17 at 17:10
  • @user0042 Good call. Fixed. – scohe001 Aug 07 '17 at 17:14