Hello all!

I am trying to take a string that has mixed uppercase and lowercase chars and then convert it to lowercase.

I am doing the following line of C++ code:

transform(theReadMessage.begin(),theReadMessage.end(),theReadMessage.begin(),theReadMessage.end(),::tolower); //theReadMessage is a string to convert to lowercase

and my C++ xCode debugger gives me this message

Too many arguments to function call, expected 1, have 2.

What am I doing wrong? Thanks in advance!!

Recommended Answers

All 7 Replies

You have too many arguments as indicated. You could use:
transform(theReadMessage.begin(), theReadMessage.end(), theReadMessage.begin(), ::tolower);

Using a lambda:

transform(theReadMessage.begin(), theReadMessage.end(), theReadMessage.begin(), [](char ch)
{
    return tolower(ch);
});

Why do you think there are too many arguments?

I thought that this was the right number of arguments, and this line of code in another project worked just fine before.

And, why should I be using a lambda function instead of tolower.

Both are the same argument, right?

Actually, I am getting the a different error, with nullptr's suggested lambda function parameter (on line 78).

For more reference, here is my code:

    //  Converts SMS language to English

    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <map>
    #include <vector>
    using namespace std;

    ///////////////////////////////////////////////////////////

    string to_lower(const string& str)
    {
        string toReturn = "";
        for (char c : str)
            toReturn += tolower(c);

        return toReturn;
    }
    ///////////////////////////////////////////////////////////

    map<string,string> lower(const map<string,string>& map)
    {
        std::map<string,string> lowered;
        for (const auto& pair : map)
            lowered.emplace(to_lower(pair.first),to_lower(pair.second));
        return lowered;
    }

    ///////////////////////////////////////////////////////////

    void Tokenize(const string& str,
                  vector<string>& tokens,
                  const string& delimiters = " ")
    {
        // Skip delimiters at beginning.
        string::size_type lastPos = str.find_first_not_of(delimiters, 0);
        // Find first "non-delimiter".
        string::size_type pos     = str.find_first_of(delimiters, lastPos);

        while (string::npos != pos || string::npos != lastPos)
        {
            // Found a token, add it to the vector.
            tokens.push_back(str.substr(lastPos, pos - lastPos));
            // Skip delimiters.  Note the "not_of"
            lastPos = str.find_first_not_of(delimiters, pos);
            // Find next "non-delimiter"
            pos = str.find_first_of(delimiters, lastPos);
        }
    }

    ///////////////////////////////////////////////////////////

    const map<string, string> RAW_SMS_CODES = lower({
        {".02","Your (or my) two cents worth"},
        {"10X", "Thanks"},
        <I AM JUST CUTTING OUT THE WHOLE LOT OF SMS-Translation pairs HERE FOR SAKES OF BREVITY>,
        {"LYMY","Love You Miss You"}

     });

    int main()
    {
        cout << "This is a program for translating your text with SMS text codes into English." << endl;
        string theReadMessage = "";
        cout << "<Enter> in a line with a message: ";

        //create theWords vector for tokenizing so there is no need to recreate it in the loop
        vector<string> theWords = vector<string>();

        //read in the entire line and get started
        getline(cin,theReadMessage);
        do {

            cout << "\n\nThe message that you entered is: " << theReadMessage << "." << endl;

            //making lowercase
            transform(theReadMessage.begin(),theReadMessage.end(),
                      theReadMessage.begin(),theReadMessage.end(),
                      [](unsigned char ch){ return tolower(ch);});

            Tokenize(theReadMessage,theWords);

            for ( auto &&token : theWords)
            {
                if (RAW_SMS_CODES.count(token) > 0)
                    //the token is actually an sms code that acts as a key in RAW_SMS_CODES
                    token = RAW_SMS_CODES.at(token);   //translating the token by getting the appropriate translation from RAW_SMS_CODES
            }

            //<DISPLAY TRANSLATED MESSAGE---- to do>
            cout << "\n<Enter> in a line with a message (empty message to quit): ";
            getline(cin,theReadMessage);

            //clear theWords for next time, if there is another iteration of the loop
            theWords.clear();

        } while (theReadMessage != "");

        //<DISPLAY PARTING MESSAGE>
    }

The error is No matching function for call to object of type '(lambda at <directory where project is stored)'. I looked at stackoverflow and I saw that one person had this error because he did not turn on C++ 11, but my xCode IDE works with C++ 11 beautifully.

What is wrong?

Any advice is appreciated, and thanks in advance.

You are still using the wrong overload for std::transform. Since you are modifying the string inplace you need the overload that takes the range to work on and the iterator to where to insert.

transform(theReadMessage.begin(),theReadMessage.end(),
          theReadMessage.begin(),theReadMessage.end(),
          [](unsigned char ch){ return tolower(ch);});

Should be

transform(theReadMessage.begin(),theReadMessage.end(),
          theReadMessage.begin(),
          [](unsigned char ch){ return tolower(ch);});
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.