Home > other >  ToLower std::vector<std::string>
ToLower std::vector<std::string>

Time:01-27

This is related to question :

String array to C function

Although everything is working fine now, the only thing I am not able to accomplish is to tolower the user input as I am getting an error :

Function

bool lookupTerm(const std::string& term, const std::vector<std::string>& possible_names) {

    transform(term.begin(), term.end(), term.begin(), ::tolower);
    for (const std::string &possible_name : possible_names)
    {
        if (possible_name.compare(term) == 0)
            return true;
    }
    return false;
}

Parameters

const std::vector<std::string> possible_asterisk         = { "star" , 
                                                              "asterisk" , 
                                                              "tilde"};
string term = "SoMeWorD";

Error

 In file included from /usr/include/c  /7.2.0/algorithm:62:0,
                 from jdoodle.cpp:5:
/usr/include/c  /7.2.0/bits/stl_algo.h: In instantiation of '_OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation) [with _IIter = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; _OIter = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; _UnaryOperation = int (*)(int) throw ()]':
jdoodle.cpp:40:64:   required from here
/usr/include/c  /7.2.0/bits/stl_algo.h:4306:12: error: assignment of read-only location '__result.__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >::operator*()'
  *__result = __unary_op(*__first);

I know that transform should be receiving a string. How can I momentarily cast the std::vector to simply string so I can get that word to lowercase?

CodePudding user response:

This is because term is const reference. Make a copy before converting it to lowercase:

bool lookupTerm(const std::string& term, const std::vector<std::string>& possible_names) {
    std::string lower(term);
    transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
    for (const std::string &possible_name : possible_names)
    {
        if (possible_name.compare(lower) == 0)
            return true;
    }
    return false;
}

You could also achieve the same effect by removing const, and taking the parameter by value:

bool lookupTerm(std::string term, const std::vector<std::string>& possible_names) {

CodePudding user response:

std::transform needs to be able to change the contents of whatever the third argument dereferences to.

That does not work in your case since term is a const object.

You can create function local object to store the transformed string.

std::string lowercaseTerm(term);
transform(term.begin(), term.end(), lowercaseTerm.begin(), ::tolower);

and then use lowercaseTerm in the following line.

  if (possible_name.compare(lowercaseTerm) == 0)
  • Related