Small help tools, train your C++ skills

additional part, not visible

I like to compare C++ developers with competitive athletes who have to train every day. This is the only way they can continuously improve their performance. It's no different with programming, only it's not the muscles and reflexes, it's new techniques. So this comparison is not so far off. Why, on the one hand because programming is not that easy, and especially C++ makes extended demands on the level of knowledge, and not everybody is able to do it, but on the other hand because we will only use language features in projects that we are sure to master.

But how can we train them, if not in our current projects? In our daily work we are constantly confronted with tasks for which we need small auxiliary tools. But instead of quickly writing them ourselves, we start searching the internet and get annoyed if it doesn't fit 100% to what we are looking for. And this is exactly the solution, we write ourselves little help tools and thus not only solve our concrete problems around the projects, we simply train new techniques with the latest compilers.


One such problem for me was formatting the source code for this blog, which cost me a lot of time and nerves in the first blog posts. You have to switch to HTML mode, replace the '<' and '>' characters in the source code with the HTML code, and if you really want to be sure, also the '&' characters. Also, I usually write my source code with an indentation of 3 characters, but here the tab value is larger. And sometimes the tabulator slips into the source code and so the display moves here.

So I decided to write a small tool, I created a simple VCL- application for this. The total development time was less than 5:00 minutes. A fraction of the time I needed before to correct the source code manually. And I would certainly spend more time looking for something suitable on the internet. We are the architects of the systems, we can solve any problem quickly and efficiently with C++. And on the side, I have once again trained the use of the standard library. 

Our application has the following main form. Surely I could extend it now, for example a button to load a source file, or buttons to paste and copy to the clipboard, and last but not least a button to close the application. Maybe I will do this later, but it has nothing to do with the core functionality. And that's all I wanted to take care of in the first step.

For the memo field I set the font to "Courier New" and the property "ScrollBars" to "ssBoth". After the program has started, I can copy the desired source code into the memo field and press the button to transform it. 

Then I set the event "OnCreate" in the IDE and implemented the method. As last I have shown the event method with your double click on the switch "btnTransform" and implemented it for the switch. The following listing shows the source code, which of course I already edited before I added it here.


//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "MainForm.h"

#include <string>
#include <algorithm>
#include <functional>
using namespace std;
using namespace placeholders;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
//---------------------------------------------------------------------------
__fastcall TfrmMain::TfrmMain(TComponent* Owner) : TForm(Owner) { }

//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormCreate(TObject *Sender) {
   Caption               = L"helper tool for blog";
   Panel1->Caption       = L"";
   btnTransform->Caption = L"transform";
   Memo1->Lines->Clear();
   }

//---------------------------------------------------------------------------
void mytransform(char para, string& strTarget) {
   switch(para) {
     case '&' : strTarget += "&"; break;
     case '<' : strTarget += "&lt;";  break;
     case '>' : strTarget += "&gt;";  break;
     case '\t': strTarget += "   ";   break;
     default:
       {
       char szBuffer[2] = { para, 0 };
       strTarget += szBuffer;
       }
     }
   return;
   }


void __fastcall TfrmMain::btnTransformClick(TObject *Sender) {
   string strSource = AnsiString(Memo1->Text).c_str();
   string strTarget = "";
   strTarget += "<pre><code class=\"language-cpp\">\r\n";
   for_each(strSource.begin(), strSource.end(), bind(mytransform, _1, ref(strTarget)));
   strTarget += "\r\n</code></pre>\r\n";
   Memo1->Text = strTarget.c_str();
}
//---------------------------------------------------------------------------

In the method "FormCreate" I set the heading and labels. Most of you may do this in the object inspector in the IDE. There are two disadvantages. Here in the picture above the listing, you can still recognize essential parts of the form, and use it in the documentation. I created the image with SnagIt, and I could add additional comments or markers. The image can then also be integrated with Doxygen or similar very good tools in a C++ environment, or uploaded to a wiki. On the other hand, you can't internationalize without delphia-helping tools, and there is too much logic in the forms themselves. You have seen in the first examples how easy it is to address the VCL or FMX from C++, even from a source code. This can of course be extended to other frameworks like Qt or MFC. C++ is the industry standard, so you should do as much as possible in source code, not in the IDE. That much of the program is not only independent of the framework but also of special forms. But you must not use dfm- or fmx- files to define their concrete labels.

The actual conversion of the individual characters is done in the global function void mytransform(char para, string& strTarget). This function gets the character to be converted as first parameter and the reference to the string variable that stores the converted text as second parameter. Since a character can always be converted into a sequence, a return as char value is not possible. Therefore, it is useful to pass the result string as a parameter. Even if we lose the possibility to use this method as a functor for the standard library. Within the multiple selection the characters can now be handled individually. Characters can also be added here if necessary.

In the event method for the switch "btnTransform" a C++ string variable "strSource" is defined, in which I copy the complete content of the memo field. Thus I can rely on C++ in the further processing. The source code should be mostly national code, therefore I use the internal conversion of Delphi and wrap the input field into a temporary variable of the type AnsiString and use the method c_str() to initialize the C++ string. For this purpose I define a second, empty string variable "strTarget", which should later take over the changed content. 

Then I use the C++- algorithm for_each() to call the functor for each character of the first string. According to the syntax, this string may only have one unary functor, in our case a method with a char character as parameter. To make the method suitable I use the C++11 method bind() and bind the second parameter as reference to the second string variable "strTarget". This results in a unary functor, only the char character remains as parameter, which matches exactly the content of a variable of type std::string. Before and after the conversion I write the necessary <pre ...> and </pre> tags into the character variable.

After successful conversion the content of the variable "strTarget" is written into the memo field, and can be copied out from there.

This small example shows a little help for daily programming. And there are many of them. Up to refactoring, searching files on your hard disk, searching project files, ... I can think of many examples from the daily environment. Use them to train your C++ skills, use the latest compilers and try out new techniques. As this example has shown, you can even save time. 

To go back to the example with the competitive athlete and training. Even an athlete usually achieves this goal only in a team, and with the help of trainers and coaches. Again, the difference is not so big. The exchange among each other is important. Roadshows and events can be good for this, a local group or colleagues. For example, a smoking break punished in other areas can be good for exchange. But on the other hand, there are also consultants and trainers in the software sector. Of course also appropriate reading.

Kommentar verfassen

* These fields are required

Kommentare

Keine Kommentare

About the Author

 


Über den Autor

Volker Hillmann

CEO, Developer, Germany, Berlin
Volker Hillmann was born in 1965 and holds a degree in mathematics with a focus on databases and data security. He has been programming in C since 1988. After first touches on a Unix machine with Turbo C 1.5 on PCs. That's how he got to know C++ in 1991 and since then he is programming in different areas with C++. After some experience in the insurance and banking industry, he founded adecc Systemhaus GmbH in 2000, of which he is still the CEO. He is also MVP at embarcadero Germany.

More posts by this author