There are a number of ways you can handle both the data and the conversions. One of the easiest ways to store your collection of strings that lends itself to easy manipulation is std::vector which then allows you to create a std::vector<std::string>
(a vector of strings). A simple range-based for
loop provides all you need to iterate over each string.
To convert the characters in each string to upper/lower case std::transform provides an easy way to convert all or some of the characters in each string (or apply any other operation to each element in the container) Your conversions to lowercase and to uppercase, then reduce to:
void stolower (std::string& s)
{
std::transform (s.begin(), s.end(), s.begin(),
[](unsigned char c) { return std::tolower(c); });
}
and
void stoupper (std::string& s)
{
std::transform (s.begin(), s.end(), s.begin(),
[](unsigned char c) { return std::toupper(c); });
}
(note: the use of std::transform
above omits the trailing return type. Adding -> unsigned char
between (unsigned char c) { return std::toupper(c); });
would provide the full form)
In each case above the transformation is applied to the range of characters from s.begin(), s.end()
, outputting the transformation beginning at s.begin()
, where the transformation itself is provided by the lambda function [](unsigned char c) { return std::tolower(c); }
or the toupper(c)
counterpart.
To implement your vector of strings and then perform the conversion to lower and then to upper, you could do:
int main (void) {
std::vector<std::string> towns = { "london", "glasGow", "HARWICH",
"NoTtInGHaM","DERBy","BriSToL" };
for (auto& s : towns) {
stolower(s);
std::cout << std::left << std::setw(12) << s << " (";
stoupper(s);
std::cout << s << ")\n";
}
}
(note: the << std::left << std::setw(12)
provided by the <iomanip>
header simply allow the output to be in tidy tabular form)
Putting it altogether and adding the needed headers, you could do:
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <cctype>
#include <algorithm>
void stolower (std::string& s)
{
std::transform (s.begin(), s.end(), s.begin(),
[](unsigned char c) { return std::tolower(c); });
}
void stoupper (std::string& s)
{
std::transform (s.begin(), s.end(), s.begin(),
[](unsigned char c) { return std::toupper(c); });
}
int main (void) {
std::vector<std::string> towns = { "london", "glasGow", "HARWICH",
"NoTtInGHaM","DERBy","BriSToL" };
for (auto& s : towns) {
stolower(s);
std::cout << std::left << std::setw(12) << s << " (";
stoupper(s);
std::cout << s << ")\n";
}
}
Example Use/Output
$ ./bin/strcasetransform
london (LONDON)
glasgow (GLASGOW)
harwich (HARWICH)
nottingham (NOTTINGHAM)
derby (DERBY)
bristol (BRISTOL)
Where each string in your vector is first converted to lowercase, and then to uppercase and output as shown above. There are many, many ways you can put the pieces together. Getting familiar with the different tools available to apply changes to each member (element) in a container using the niceties provided by the Standard Template Library, can make your work shorter and generally more robust. Let me know if you have further questions.