Utility programs are short single purpose programs that run from the command line. They may need a configuration file though often they don't and if they do it will be short, most likely in plain text rather than XML.
UNIX was built on the principle of small, often simple tools, that can be combined in many ways to perform often complex tasks.
This tutorial is about writing a typical utility in C++, based on an identical utility in C, and the downloadable source code includes a fully working utility.
Like the C utility this is a simple utility that counts the lines of code, comments and blank lines in a file. It's meant for .c,.cpp, .h and .hpp files and understands C and C++ comments in the specified file. This tutorial is to show that for many utilities C++ can be the better choice.
- Fancy Game Programming?
This is meant for running on Windows and is compiled using Visual C++ 2010 Express. I'll eventually write the Linux equivalent using g++.
- Need to Learn C++ Programming?
What is a Utility Program?
It's just a simple program run from the command line, usually with no database access that does a simple task. It has the following features. (Note this is my definition):
- Can have command line option arguments usually separated by - or / (use - or / on \Windows, just - on Linux as / is for folders).
- Uses stdiin, and stdout so Windows pipeline commands !! > and < all work
- Includes a simple help triggered by no input or -h or --help command line inputs
- View the source code cloc.txt (as a .txt file).
Implementing the line count utility
This counts how many lines of code are in a file, distinguishing between code and comments and counting blank lines as well. This means reading the entire file line by line and seeing if any of the following are found:
- If it's a blank line, just increment numBlanks.
- It starts with a C++ comment //. Add 1 to numComments
- If the "incomment" flag is set does the line contain a C end comment */. if so it clears the flag
- It starts or contains a C start comment /*. This sets the "incomment" flag
If none of these are true then:
The only possibly issue is if a C++ comment is used inside of a C comment as in
// Will this break?
It shouldn't cause any issues. Whether or not a C++ comment // occurs inside a C comment is irrelevant. That line is a comment and does not alter the incomment flag.
Creating the Counter Class
Being C++, wrapping everything in a class improves the quality of the code. The constructor calls Reset, a private method to reset the three counter variables (numLines, numComments and numBlanks).
The Counter::ProcessFile() method function does all of the donkeywork. If any errors occur, it retains the error message and the public method HasError() returns true/false. If it's false then public method Counter::GetResults() returns the results ( the three numbers, numLines, numComments and numBlanks).
In this version, I've used std::string, so there's little individual character manipulation apart from using strncmp for checking the command line parameters. This use of std::string is one of the things that is much better in C++ than C. I use string::find for searching. If the string isn't found it returns a value std::string::npos so != that means it found it.
To check for blank lines I needed a string trim function and like the C utility found a nice short one on StackOverflow from Evan Teran so thank you to Evan and StackOverflow.
Notes: This is fairly simple, and fast but it doesn't completely correctly deal with comments on lines of code. A line like this:
}; // Is this counted as code or comment?
It could be argued that it's either code or a comment, but the way // is only found at the start of a line (that's why trim was needed) means it will only treat this as a line of code, and not be counted as a comment.
I think it should be code, because the number of lines of code is a more important metric than the number of lines of comments. If it counted as both then the total would exceed the number of lines in the file.
- See more How to do things in C++.