Using the Transform() Algorithm to Change a String’s Case

ommand line interpreters, HTTP requests, and SMS messages are only a few of the applications in which different letter cases merely cause noise. To overcome this problem, such applications usually convert all strings to uppercase before any further processing.



Sadly, most of these apps use C-style strings and ad-hoc, in-house conversion routines that more often than not suffer from bugs, illegibility, and performance overhead. The std::string class provides more than a hundred member functions and overloaded operators. Yet, none of these functions transforms a string to uppercase or lowercase letters.



Use the STL transform() algorithm to change a string’s case easily.Converting the Hard Way
There are numerous ways to change the case of a string. A naive implementation might look like this:

 #include #include using namespace std;int main(){ string s="hello"; for (int j=0; j

Though functionally correct, this loop is a maintenance headache. To apply a different type of transformation to the string, say to convert it to lowercase or transliterate all characters to their Cyrillic equivalent, you'll have to rewrite the loop's body. To improve the design, separate the string transformation into two operations: one that iterates through the string's elements and one that actually transforms every element. You gain more flexibility by decoupling these operations and simplify future maintenance.

Step 1: Iteration
The transform() algorithm defined in is rather flexible. Not only does it separate between the iterations and transformation operations, it also allows you to transform only a portion of the string. In addition, you can store the result in a different destination, should you prefer to keep the original string intact. The transform() algorithm has two overloaded versions but we will use only the following one:

OutputIterator transform(InputIterator first,                         InputIterator last,                         OutputIterator result,                         UnaryOperation unary_op);

You can find an explanation about the different iterator categories here. The first and second arguments are iterators pointing to the beginning and the end of the sequence being transformed. The third argument is an iterator pointing to the beginning of the destination sequence. If you wish to overwrite the current string, result and first should have identical values.

Step 2: Transformation
The fourth argument is a unary operator. It can either be an address of a function that takes a single argument or a function object. STL algorithms don't really care whether a unary operator is a function object or an address because they merely append () to it and let the compiler takes care of the rest. This example uses the standard toupper() function declared in :

#include  // for toupper#include #include using namespace std;string s="hello";transform(s.begin(), s.end(), s.begin(), toupper);

Alas, the program above will not compile because the name 'toupper' is ambiguous. It can refer either to:

int std::toupper(int); // from 

or

template    charT std::toupper(charT, const locale&);// from   

Use an explicit cast to resolve the ambiguity:

std::transform(s.begin(), s.end(), s.begin(),                (int(*)(int)) toupper);

This will instruct the compiler to choose the right toupper().

Design Improvements
There are ways to further benefit from using transform(). Suppose you need to transform a string to lowercase rather than uppercase. You change the transform() call to:

std::transform(s.begin(),                s.end(),                std::back_inserter(s1),                std::tolower);

It's not much of an improvement compared to the original for loop, is it? To avoid intrusive code changes such as this, use an additional level of indirection. Instead of passing a function's name as an argument, use a pointer to a function. This way, you can decouple the transform() call from the customers' requirements. Furthermore, the use of a pointer enables you to postpone the function binding to runtime:

int (*pf)(int)=tolower; transform(s.begin(), s.end(), s.begin(), pf); //lowercase

Notice that you don't need to change the transform() call now if you wish to apply yet another transformation:

pf=tocyrillic; // just an exampletransform(s.begin(), s.end(), s.begin(), pf); // Cyrillic

Conclusions
If using transform() to convert a string to uppercase seems like overkill to you, you're probably right. The string transformation was a red herring, though. The point was to show how to use transform() to manipulate sequences in a generic fashion. By using transform(), transforming a sequence of integers to their negative or square root values is a cinch:

template  class negate{public: T operator()(T t) { return -t;}};int arr[]={1, 2, 3};transform(arr,           arr+sizeof(arr)/sizeof(int),           arr,           negate()); // arr = {-1, -2, -3}
Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

The Latest

Why transparent code is a good idea

Why Transparent Code is a Good Idea

Code is used to make up the apps and software we use every day. From our favorite social media platforms to our online banking services, code is the framework used to build these tools that help make our lives easier. Code is complex. Software today requires large teams of programmers

The Role of WordPress Hosting in Website Speed and Performance

The Role of WordPress Hosting in Website Performance

The term “WordPress hosting” refers to a specific type of web hosting service that offers hardware and software configurations tailored to the needs of WP sites. It’s important to remember that a WP hosting package is not required to host WordPress webpages. WP web pages are also compatible with standard

Data Privacy vs. Data Security: What you Should Know

Data Privacy vs. Data Security: What you Should Know

Data privacy and data security are often used interchangeably, but they are two completely different things. It’s important to understand the difference for anyone who handles sensitive information, such as personal data or financial records. In this article, we’ll take a closer look at data privacy vs. data security. We’ll

Concerned About Company Data Security?

Company Data Security Concerns? Follow These 9 Tips

The days of doing all of one’s work at an office have long since passed. With technological progress, you can do most of the work from a remote location. It allows you to go on vacation anytime without affecting your work. It’s common to work from another location these days.

How to Access and Website With a Free VPN for PC

How to Access and Website With a Free VPN for PC

In the online world of today, you will come to realize that it is all-encompassing. The world has become hyper-digitalized and geared towards cyberspace. Whether it was always going to happen or driven by external factors. At the same time, events like the COVID-19 pandemic have shifted our activity toward