1

Im working with html, javascript and c++. I need convert a string to uppercase and lower case and return both of them to the front end. I can only return the string once in either uppercase or lowercase. I have it commented out since i can only return one value correct?

I have successfully converted the string into lowercase and uppercase but i was wondering if i could return both of the values instead of one.

std::string upperCase(std::string words){
    for(int i = 0; i < words.size(); i++) {
        words.at(i) = toupper(words.at(i));
        //words.at(i) = tolower(words.at(i);
    }
    return words;
}

Input:HeLLo Output: Lower: hello Upper: HELLO

Eddy
  • 75
  • 7
  • Can you just have your function return "Lower: hello Upper: HELLO"? I ask this to illustrate that there is not enough information on the context and the interface for your function. How does the environment expect the two returns? Can you change the interface from one function call to two? Can you change the interface to extract the two parts from one return value (this is practically what 4386427 proposes above). – Yunnosch Sep 23 '19 at 05:48
  • Alternatively, consider json as packing format. It goes very well with javascript. (Note the escape characters though) – Stefan Sep 23 '19 at 06:07
  • Possible duplicate of [Returning multiple values from a C++ function](https://stackoverflow.com/questions/321068/returning-multiple-values-from-a-c-function) – Fade Sep 23 '19 at 06:29

4 Answers4

2

It is correct that a function can return at maximum one value. Since you need two return values, you'll have to pack those into some other data type.

There are several options. You can use std::tuple, you can make a struct/class that holds two strings, you can return a vector of strings, etc.

The example below uses a vector to hold the strings.

#include <iostream>
#include <vector>

std::vector<std::string> upperLowerCase(std::string words){
    std::vector<std::string> res;
    res.push_back(words);
    res.push_back(words);
    for(int i = 0; i < words.size(); i++) {
        res[0].at(i) = toupper(words.at(i));
        res[1].at(i) = tolower(words.at(i));
    }
    return res;
}

int main() {
    std::vector<std::string> v = upperLowerCase("HeLLo");
    std::cout << "Upper: " << v[0] << std::endl; 
    std::cout << "Lower: " << v[1] << std::endl; 
    return 0;
}

And the example below uses std::tuple

#include <iostream>
#include <tuple>

std::tuple<std::string, std::string> upperLowerCase(std::string words){
    std::string upper = words; 
    std::string lower = words; 
    for(int i = 0; i < words.size(); i++) {
        upper.at(i) = toupper(words.at(i));
        lower.at(i) = tolower(words.at(i));
    }
    return std::make_tuple(upper, lower);
}

int main() {
    std::tuple<std::string, std::string> t = upperLowerCase("HeLLo");
    std::cout << "Upper: " << std::get<0>(t) << std::endl; 
    std::cout << "Lower: " << std::get<1>(t) << std::endl; 
    return 0;
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • 1
    I don't recommend `std::vector` for this. Unnecessary overhead, plus the alternatives like `std::tuple` or a custom `struct` have safe get. – bolov Sep 23 '19 at 06:00
2

std::string is not the best choice to do that. Try to use std::tuple, or a simple array std::string[2].

std::string str_tolower(std::string s)
{
    std::transform(s.begin(), s.end(), s.begin(),
        [](unsigned char c)
        {
            return std::tolower(c);
        });
    return s;
}
std::string str_toupper(std::string s)
{
    std::transform(s.begin(), s.end(), s.begin(),
        [](unsigned char c)
        {
            return std::toupper(c);
        });
    return s;
}
auto cases = std::make_tuple(str_toupper(s), str_tolower(s));
Daniofb
  • 71
  • 6
1

You can use std::pair.

std::pair<std::string,std::string> upperCase(std::string words){
    int len = words.length();
    std::pair<std::string,std::string> ret;
    ret.first.resize(len);
    ret.second.resize(len);
    for(int i = 0; i < words.size(); i++) {
        ret.first.at(i) = toupper(words.at(i));
        ret.second.at(i) = tolower(words.at(i);
    }
    return ret;
}
0

You can use a struct that contains upper and lower cases:

#include <iostream>
#include <string>

struct Cases
{
    std::string upperCase;
    std::string lowerCase;
}

Cases getCases(std::string words)
{
    Cases itsCases;
    for(int i = 0; i < words.size(); i++) 
    {
        itsCases.upperCase.at(i) = toupper(words.at(i));
        itsCases.lowerCase.at(i) = tolower(words.at(i));
    }
    return itsCases;
}

int main() 
{
    std::cout << "Upper Case: " << getCases("HeLLo").upperCase << std::endl; 
    std::cout << "Lower Case: " << getCases("HeLLo").lowerCase << std::endl; 
    return 0;
}