ALERT!
Click here to register with a few steps and explore all our cool stuff we have to offer!
Home
Upgrade
Credits
Help
Search
Awards
Achievements
 10762

C++ Character Case Inversion Example - Iterators

by bitm0de - 01-14-2016 - 02:47 AM
#1
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. :)
Reply
#2
Awesome share :D
Reply
#3
I haven't gotten much other than comments like yours though so I'm assuming there are not C++ coders on here lol.. Just people that claim they are or they don't see my posts .
Reply
#4
nice tut. thanks dude
Reply
#5
Nice share keep the good work up
Reply

Users browsing: 4 Guest(s)