C++ Character Case Inversion Example - Iterators

by bitm0de - 05-01-2016, 03:32 AM
Junior Member
Posts:
57
Joined:
Jan 2016
Likes:
5
Credits:
32
Reputation:
-4
2 Years of Service
#1
OP
Posted: 05-01-2016, 03:32 AM (This post was last modified: 06-01-2016, 01:15 AM by bitm0de.)
Thought I'd post a small example of iterators and a few template functions in C++ to invert the case on each character within a std::basic_string<char> object.

Code:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <cctype>

int main()
{
  std::string s("This is A simple TEST");
  std::transform(s.begin(), s.end(), s.begin(), [&](char ch) {
      return isalpha(ch) ? ch ^ 32 : ch;
      });
  std::copy(s.begin(), s.end(), std::ostreambuf_iterator<char>(std::cout));
  std::endl(std::cout);
}

The compilation flag I used is in the image below: (Note - I use mingw-w64 on my Windows machine for most things, I do have VS 2015 but I only really use it for larger C/C++ projects)
[Image: 6ZyXfAU.png]

I'm using std::ostreambuf_iterator because std::ostream_iterator is less efficient; it creates a new sentry object after destroying the old once per character written to the output stream. In this case I also don't need to write anything but the characters from std::string 's' so it is a very viable solution here.

The other thing I could have done is use the overloaded = operator to append a newline to the output sequence of the std::ostreambuf_iterator which points to std::cout (the stdout object), because std::copy returns the output iterator passed into the function.

i.e.
Code:
std::copy(s.begin(), s.end(), std::ostreambuf_iterator<char>(std::cout)) = '\n';

This is harder to understand if you didn't know what std::copy returned and the semantics of the = operator are less obvious in this case because they do not assign to the variable, it passes something to the object in this case. Additionally, the other thing about this is that *conceptually* it should not flush the output buffer -- However, most implementations of standard output are line buffered anyways too, so I wouldn't be missing much with using std::endl over inserting the '\n' character.

Last thing I guess to mention within the lambda is that this method relies on isalpha() to determine which characters we should *invert*. If you cared about the locale() being used -- which in default C is based on what isupper() and islower() return -- then you could use the templated version for C++.

Prototype:
Code:
template <class charT>
bool isalpha (charT c, const locale& loc);

If you have any questions, ask. :)
Nan Ihier Gelair Mordor
Divine
Posts:
2,635
Joined:
Jan 2015
Likes:
321
Credits:
8,666
Reputation:
92
3 Years of Service
#2
Posted: 11-01-2016, 01:49 PM
Thank you for sharing this!
Do not let your difficulties fill you with anxiety, after all it is only in the darkest nights that stars shine more brightly. - Ali(a.s)

Developer( PHP, Python, C++, HTML+CSS, JS I am available for Hire. Message Me for details.
Newbie
Posts:
15
Joined:
Jul 2017
Likes:
0
Credits:
9
Reputation:
0
1/2 Year of Service
#3
Posted: 13-07-2017, 07:45 PM
Is this code for Ps3 or what
The last reply on this thread is older than a month. Please do not unnecessarily bump it.
Register an account or login to reply
Create an account
Create a free account today and start posting right away. It only takes a few seconds.
Login
Log into an existing account.
1 Guest(s)