Inverting Strings function not working

Pages: 12
Hello, I am new to C++ and I trying to create a program that inverts a strings lowercase letters to upper and vice-versa.
I believe the error is in what I am returning within my function. Below is what I have written so far.

The program when compiled does not produce any errors, but after inputting the string, the output is just the same string I inputted.

Both my main.cpp and manip.cpp have included my header file which contains all of the preprocessor directives such as:
#include<iostream>
#include<string>
#include<cctype>
#include<iomanip>
and,

using namespace std; // I know this is not convention, but professor requires it this way.

Any suggestions would be most helpful. Thank you!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
  #include "manip.h"

  int main()

{
   string input;
   int selection;
   cout << "Please enter a string: " << endl;
   getline(cin,input);

   inverseString(input);
   cout << input << endl;

  system("pause");
  return 0;

}

string inverseString(string input)
{
  char c;
  for (unsigned int i = 0; i < input.length(); i++)
  {
      c = isalpha(input[i]);
      if(isupper(c))
      {
         tolower(c);
      }
      else 
      {
        toupper(c);
      }
    return input;
  }

}
tolower() and toupper() don't modify the argument you pass, but they return the upper/lower case character.

Thus you simply need to assign that to input[i]
like
 
input[i] = tolower(c);
Thank you, I understand the logic of what you said.


string inverseString(string input)
{
char c;
for (unsigned int i = 0; i < input.length(); i++)
{
c = isalpha(input[i]);
if(isupper(c))
{
input[i] = tolower(c);
}
else
{
input[i] = toupper(c);
}
return input;
}

Does this mean outside of the for loop I should assigned input[i] to input?
So: input = input[i];
then return input?
> Does this mean outside of the for loop I should assigned input[i] to input?
No, you need not do anything, input is a string while input[i] refers to the ith character of that string, when you modify input[i], input string is also modified.

Now regarding your code
 
c = isalpha(input[i]);

This line isn't right.
isalpha() returns true if input[i] is an alphabet, false otherwise
Thus if input[i] is an alphabet, c is assigned the value 1, not the character.
This is what you need to do
1
2
3
4
5
if (isalpha(input[i])
{
    c = input[i]
    ....convert to upper/lower
}
Last edited on
@a k n
This may result in a complier error.
if (isalpha(input[i])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
string inverseString(string input)
{
char c;
for (unsigned int i = 0; i < input.length(); i++)
{
 
   if(isalpha(input[i]))
   {
       c = input[i];
       input[i] = tolower(c);
   }
   else if(isalpha(input[i])) 
   {
         c = input[i];
         input[i] = toupper(c);
    }
   return input;
}


I am not getting a compile error, but my output is still the same.
When I type in the string, "Hello" the output is the same.

Does this not have to do with my return statement?
This is the corrected version, I apologise as I didn't make it clear from the last message but this should clear things up.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
string inverseString(string input)
{
char c;
for (unsigned int i = 0; i < input.length(); i++)
{
 
   if(isalpha(input[i]))
   {
       c = input[i];
       if (islower(c))
           input[i] = toupper(c);
       //else if (isupper(c))
       else //obvisouly it's going to be uppercase
           input[i] = tolower(c);
   }
   return input;
}
Last edited on
closed account (48T7M4Gy)
HINT: If you examine the ASCII table you can see that uppercase and lowercase letters have systematically different ASCII codes which you might take advantage of instead of using toupper which, even though it shows a lot of promise, might not be successful.

1
2
3
4
5
char xx = 78;
cout << xx << endl;

char yy = 110
cout << yy endl;


N
n


http://www.asciitable.com/
Last edited on
> even though it shows a lot of promise, might not be successful

Can you elaborate ?
closed account (48T7M4Gy)
Can you elaborate ?


Yeah, I can elaborate. The reason I said it that way is that, on face value, those are the functions I also first explored to solve the problem. So I looked up their function reference and decided, well maybe toupper() and tolower() are worthwhile to keep going with (and I don't want to stop you) but even if I can get it to work, the ASCII code way is less trouble.
It seems even with the corrections, it is still not producing the proper output.
Any other possible problems?

Unfortunately I am required to use the toupper() and tolower() functions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

string inverseString(string input)
{
char c;
for (unsigned int i = 0; i < input.length(); i++)
{
 
   if(isalpha(input[i]))
   {
       c = input[i];
       if (islower(c))
           input[i] = toupper(c);
       //else if (isupper(c))
       else //obvisouly it's going to be uppercase
           input[i] = tolower(c);
   }
   return input;
}


Could it be something in my main():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

{
   string input;
   int selection;
   cout << "Please enter a string: " << endl;
   getline(cin,input);

   inverseString(input);
   cout << input << endl;

  system("pause");
  return 0;

}


or maybe something in my header file?

1
2
3
4
5
6
7
8
9
10
#include<iostream>
#include<string>
#include<iomanip>
#include<cctype>

using namespace std;

string inverseString(string);

Last edited on
In main()
input = inverseString(input);
Does that help you?
closed account (48T7M4Gy)
That's where it is closed!!! Well done :)

This problem highlights the need for good variable naming.
Last edited on
closed account (48T7M4Gy)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
include <iostream>
#include <string>
  
using namespace std;

string inverseString(string ); //<--

int main()
{
   string input;
   cout << "Please enter a string: " << endl;
   getline(cin,input);

   string answer = inverseString(input);
   cout << answer << endl;

  system("pause");
  return 0;
}

string inverseString(string someInput)
{
    string str = someInput;
    char c;
    
    for (unsigned int i = 0; i < str.length(); i++)
    {
        c = str[i];
        
        if (islower(c))
            str[i] = toupper(c);
        else
            str[i] = tolower(c);
   }
   
   return str;
}
closed account (48T7M4Gy)
For interest sake only:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>

std::string inverseString( std::string );

int main()

{
   std::string input;
   
   std::cout << "Please enter a string: \n";
   std::getline(std::cin,input);

   std::string answer = inverseString(input);
   std::cout << answer << std::endl;
   
   return 0;
}

std::string inverseString(std::string someInput)
{
    std::string str = someInput;
    char c = ' ';
    
    for (unsigned int i = 0; i < str.length(); i++)
    {
        c = str[i];
        
        if( c >= 'A' && c <= 'Z' )
        str[i] = c + 'z' - 'Z';
    
        if( c >= 'a' && c <= 'z' )
        str[i] = c - 'z' + 'Z';
    }
    
    return str;
}
Last edited on
Yes, all of your suggestions were a big help! Thank you very much.

I see why it was outputting the same string I was inputting. Like @ a k n said earlier, the function is just returning the character with an Upper/Lower case character depending.

So in order to print the result it is necessary to assign the new value to a variable then print the variable.
Yeah, glad it helped :)
closed account (48T7M4Gy)
So in order to print the result it is necessary to assign the new value to a variable then print the variable.


Yes in this case. If you haven't already learned it there is another method called pass by reference which enables you to pass the input but instead of making a copy within the function this way here, you can change the original string.
@kemort

I fail to see how directly exploiting ASCII is better than using the more intuitive and portable ctype functions ?
From the function names itself, it is obvious what they are doing while your method assumes knowledge that in ASCII alphabets are laid out sequentially, which isn't obvious to a beginner. Nor did you answer my question on how it might not be successful.
Never mind the fact that virtually every platform we'll encounter will be ASCII compatible, it sounds like a good practice to me to handle things like this with a proper function (even though things like EBCDIC exist).
Pages: 12