2013/11/15

Read user input or Enter

Posted in Code tagged , , , , at 14:48 by Orjan

In an interactive shell application, you might want to ask the user for value, or let them stick with the default or current value. In such cases, it’s quite handy to be able to accept a press on the Enter key as a shorthand for keeping the current.

Number of runs (5): 
Snoffle variant (pink): red	

In the example above, the user has pressed enter without giving a value when prompted for number of runs, and has thus accepted the current setting of 5. In contrast, the user has decided to change the snoffle variant from pink to red. Presumably the user (and the programmer) knows the significance of all this.

The problem is that while the standard input stream std::cin is good at reading and parsing data, it will read as much as it needs, and no more. This means that for strings, it will read until the first whitespace character, so you only get one word. For ints and floats, it will ignore any initial whitespace characters, like space and newline, until it finds the beginning of a number (or an invalid character), and leave anything after the number, which may lead to there being a newline in the buffer when you come next to read a string.

The solution lies in always reading everything until newline, which is what the standalone function std::getline is for, into a string, and then, once we have the whole user input, attempt to parse it. By using a std::stringstream, we’ll be relying on the same parsing routines as std::cin would feed into. Making it a template function is only natural, since the streams (both std::cin and std::stringstream) are designed to work with ttemplate types.

#include <iostream>
#include <sstream>

/*! Read user input until Enter is pressed. 
    \tparam T type of data to read
    \param val will hold the given input, if any
    \return false if Enter was pressed at once, true if data was given
*/
template <typename T>
bool get_user_input(T& val)
{
    std::string s;
    std::getline( std::cin, s);
    if (s.empty())
        return false;
    std::stringstream ss;
    ss << s;
    ss >> val;
    return true;
}

This is very simple and straigtforward to use:

  int runs = get_number_of_runs();
  std::cout << "Number of runs (" << runs << "): ";
  if (get_user_input(runs))
    set_number_of_runs(runs);
  std::string snoffle = get_snoffle();
  std::cout << "Snoffle variant (" << snoffle << "): "
  if (get_user_input(snoffle))
    set_snoffle(snoffle);

You’ll note that we get the current value, so we can display it, and only replace it if we have been given a new one.

2011/08/05

All your base64 are different to us

Posted in Code, CodeProject tagged , , at 13:03 by Orjan

The C++ source files for the stand-alone base64 encoder and decoder discussed in this post, plus a separate implementation of quoted-printable (RFC 2045, section 6.7), and the hex string converter I presented last year, can be found here:
http://coolcowstudio.co.uk/source/cpp/coding.zip.

There is a quote that goes “Standards are great! Everyone should have one.” or something along those lines. (Somewhat ironically, this quote, too, has many different variations, and has many attributions. The earliest I’ve found attributes it to George Morrow in InfoWorld 21 Oct 1985).

A case in point is the base64 encoding. Put simply, it’s a method of encoding an array of 8-bit bytes using an alphabet consisting of 64 different printable characters from the ASCII character set. This is done by taking three 8-bit bytes of source data, arranging them into a 24-bit word, and converting that into four 6-bit characters that maps onto the 64-character alphabet (since 6 bits is 0-63).

The original implementation was for privacy-enhanced e-mail (RFC 1421), then altered slightly for MIME (RFC 2045), and again in its own standard (RFC 4648).

When I was looking at base64, I was interested in three different varieties or flavours, namely the MIME version, the (per RFC 4648) standard base64, and base64url. These differ in how they handle line breaks and other illegal characters, what characters are used in the 64-character alphabet, and the use of padding at the end to make up an even triplet of bytes.

Read on…

2010/07/22

Home on the range

Posted in Code, CodeProject tagged , , at 18:13 by Orjan

Continuing on the train of thought started in bounds class I presented a few days ago in Bounds, and staying within them.

As so often happens, just having bounds available made me think of what variants of it could be useful. For instance, it would be handy to have it work for floating point or non-POD types, which isn’t possible as it is written. Since the bounds class uses ‘non-type template parameters‘ for its limits, only integer types and enums are accepted.[1]

Even disregarding this restriction, I found that I had use for a dynamic range class, as opposed to the static bounds which has its boundaries set at compile time. Just a simple one, and like std::pair only having two values, but with both of the same type, and with them guaranteed to be ordered.

The last part there would make it a bit more complex than the simple std::pair struct, as I’d need to validate the values given in order to ensure that the minimum was lower than or equal to the maximum, but still, a simple enough little class. Read on…

2010/07/14

Static assert in C++

Posted in Code, CodeProject tagged , at 13:59 by Orjan

Just a quick little note today, to clarify something I mentioned in passing the other day in Bounds, and staying within them. I said I “I added a static assert to validate the template parameters at compile time”, and it’s probably worthwhile to spell out how that works for those who haven’t seen it before.

As a rule, the earlier you find an error, the easier it is to identify and fix. The errors spotted by your compiler are, naturally, easier to fix than the errors exhibited by your program as it is running. A static assert helps by letting you sanity-check the code you write, and generating a compiler error if you write code that is syntactically correct, but logically incorrect.

For instance, the bounds class takes a lower and upper boundary as template parameters, and assumes them to be ordered. Say we didn’t have a static assert, and used it to find out if a randomly generated world in a space game is suitable for colonisation, and what animals can be introduced.

typedef bounds<int, -5, -30> polarbear_temp;
...
// generating a randomworld and it's temperature
...
// Adding various animals
if (polarbear_temp::in_bounds(randomworld_temp))
...

This would lead to a universe completely devoid of polar bears (which I’m sure we all can agree would be a bad thing), because there is no temperature that can be both greater than -5 and less than -30.

Because the limits are known at compile time, it makes sense to check them at compile time, too.

Read on…

2010/07/12

Bounds, and staying within them

Posted in Code, CodeProject tagged , , at 13:39 by Orjan

How often have you written a line of code that looks something like this?

if (3 <= var && 14 >= var)

There might (read “should”) be named constant variables instead of the magic numbers there, but in essence it’s a very common piece of code for a very common type of test – is this value within pre-defined, constant bounds?

Some years ago, I was working on a project that had lots of tests like that, and I came across a surprisingly large number of errors one can commit with this simple code. For instance:

// non-paired constants
if (minTempUK <= var && maxTempUS >= var)

// wrong comparison 
if (minTempUK < var && maxTempUK >= var)

// test wrong way around  
if (maxTempUK <= var && minTempUK >= var)

// maxTempUK is compared to bool  
if (minTempUK <= var <= maxTempUK)

// bitwise rather than logical AND    
if (minTempUK <= var & maxTempUK >= var)  

All of these are legal C++, and only the last two or three might generate compiler warnings. The last would still work properly, but is a bit iffy. If it isn’t a typo, someone needs to read up on operators. In most cases, these errors were typos (except the fourth, which was written by someone more used to other languages), but since they compiled, and sort of worked, they only showed up as bugs every now and then, at the edge cases. And because the code looks sort of okay, it was hard to spot the typos right away.

Read on…

2010/07/08

Redux: RAII adapter for Xerces

Posted in Code, CodeProject tagged , , , at 18:15 by Orjan

In my previous entry, C++ RAII adapter for Xerces, I presented a simple memory management wrapper for Xerces types. Because of the way Xerces manages memory, I said, the quite handy boost::shared_ptr couldn’t be used, so I wrote the memory management code myself to produce a safe wrapper in the style of std::auto_ptr.

However, as Alf P. Steinbach pointed out, I was wrong, in that boost::shared_ptr could be used by taking advantage of the custom deleter facility offered by that class. One benefit is that I can get rid of my hand-rolled memory management, but on the other hand, I’ll have to adjust the public interface to reflect different semantics.

Read on…

2010/05/14

C++ RAII adapter for Xerces

Posted in Code, CodeProject tagged , , , at 13:22 by Orjan

Xerces is a powerful validating XML parser that supports both DOM and SAX. It’s written in a simple subset of C++, and designed to be portable across the greatest possible number of platforms. For a number of reasons, the strings used in Xerces are zero-terminated 16-bit integer arrays, and data tends to be passed around by pointers. The responsibility for managing the lifetime of the DOM data passed around is usually Xerces’, but not always. Some types must always be released explicitly, while for others, this is optional.

In other words, this is a job for the RAII idiom. Alas, we can’t reach for our boost::shared_ptr[1] or std::auto_ptr, since Xerces has its own memory manager, and when Xerces creates an object for you, it is not guaranteed to be safe to simply call delete. Instead, you must call the object’s release() function.

Read on…

Follow

Get every new post delivered to your Inbox.