0

I know how to lower a sentence, but I wanted to use my string modification class to do so. For some reason, using my Strmod object does not work, but doing it through main works. Here is the sentence lowering code:

TL;DR, answer: turns out I needed to pass the string to the object by reference! Below is the code that works:

transform(statement.begin(), statement.end(), statement.begin(), tolower);

And here is my class for it:

class Strmod {
public:
string lower(string &s) {
    transform(s.begin(), s.end(), s.begin(), tolower);
    return s;
    }
};

And I call it like this:

int main(){
    string statement = "";
    getline(cin, statement);
    Strmod mod;
    mod.lower(statement);
    cout << statement;    //for debugging
}
  • 2
    You may want to add the appropriate language tag (and presumably remove some generic tag like 'object'). –  Jan 11 '16 at 08:55

3 Answers3

0

Try this, It should work

string data = "";
getline(cin, data);
transform(data.begin(), data.end(), data.begin(), ::tolower);
cout<<data;

The:: refers to the global namespace than the std:: standard namespace, Or else You'll have to type cast it to the relevant return type of it like (int (*)(int))std::tolower if you want to refer it to the std namespace

Includes:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
sameera sy
  • 1,708
  • 13
  • 19
0

Let me explain the difference between the version that does not work and that works. In the working one, you are modifying the string statement and cout'ing it, so everything works as expected. However, in the version that does not work, you call the method lower and supply it the string statement by value. That means, the method gets a copy of statement. The method works on the copied version and returns it. Since you do not capture the return of the function, your statement variable that you refer to in the main method is left unmodified. It was passed by value, that is to say only a copy of it was sent to the method. Try this version of your non-working code to see it actually does what you want to accomplish:

int main(){
    string statement = "";
    getline(cin, statement);
    Strmod mod;
    statement = mod.lower(statement); // see we are assigning the modified value to statement in order to capture the changed string
    cout << statement;    //for debugging
}

Or this one, where your method's signature is changed to allow pass by reference:

class Strmod {
public:
string lower(string &s) { // see the signature of the method changed for reference passing
    transform(s.begin(), s.end(), s.begin(), tolower);
    return s;
    }
};
Selçuk Cihan
  • 1,979
  • 2
  • 17
  • 30
  • Thank you! It seems that the first option worked the best. Also, where can I read about reference passing in C++? – IgnisImperatrix Jan 12 '16 at 22:55
  • Check this for a beautiful explanation http://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value – Selçuk Cihan Jan 13 '16 at 06:44
0

The class has nothing to do with why you think it doesn't work. The problem has to do with parameter passing. You are taking the method's string argument by copy.

You would see the same result from a free standing function.

string lower(string s) {
    transform(s.begin(), s.end(), s.begin(), tolower);
    return s;
}

string s = "TEST";  
lower(s);
std::cout << s;  //still "TEST"

The solution is to pass by reference.
Notice I returned a reference too, to allow nested function calls.

string& lower(string &s) {
    transform(s.begin(), s.end(), s.begin(), tolower);
    return s;
}

You probably don't want to instantiate the class everytime to call the method either. If so, consider making the method static.

struct Strmod {
    static string& lower(string &s) {
        transform(s.begin(), s.end(), s.begin(), tolower);
        return s;
    }
};

string s = "TEST";
Strmod::lower(s);

But the language feature you are probably looking for, is a namespace.

namespace Strmod {
    string& lower(string &s) {
        transform(s.begin(), s.end(), s.begin(), tolower);
        return s;
    }
};

string s = "TEST";
Strmod::lower(s);
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271