Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Literal Converter for Integers

0.00/5 (No votes)
19 Aug 2009 1  
A helper class to convert integer literals between decimals, octals, binaries and hexadecimals.

LiteralConversion_gui.png

LiteralConversion_cli.png

Introduction

Electronic engineers often feel the need to plot experiment data observed from electronic instruments (e.g. Oscilloscope meters). More often than not, the data is stored in one format (e.g. hexadecimal), while the plotting software needs another input format (e.g. decimal). This is quite inconvenient. I finally decided to wrap the conversion into a C++ class: CLiteralConverter. In practice, integer literals usually come in four guises: decimal, octal, hexadecimal, and binary literals. So CLiteralConverter only provides conversion between these four formats.

Background

Instead of any hand-crafted algorithm, CLiteralConverter completely takes the power of the standard iostream library. The idea is simple:

1. Tokenize

Using BOOST Tokenizer library, the original data string can be easily parsed and broken into conversion units. A typical usage is shown below:

// 1. initialise a seperator functor
boost::char_separator<char> sep(", ;");
// 2. initialise the tokenizer with the string and the seperator
boost::tokenizer
<boost::char_separator<char> > tok("o,riginal str; ing",sep);
// 3. iterate to get each tokenized result.
boost::tokenizer
<boost::char_separator<char> >::iterator itr, itr_end;
itr = tok.begin();
itr_end = tok.end();
for(; itr != itr_end; ++itr)
{
    ...
}

2. Convert and Store values

After the tokenizing, units are converted into std::size_t values and stored as std::vector<std::size_t>. This step is accomplished with the help of manipulators for streams: std::hex, std::oct and std::dec. Then we can read the units as hexadecimal, octal and decimal values. However, there is no support for binary notation. Fortunately, we can read binary by using the class bitset. The usage is demonstrated below:

// for reading hex, dec and oct
stringstream ss;
std::ios::fmtflags fmt;
size_t lVal;

fmt = std::ios::hex/* std::ios::dec, std::ios::oct */;
ss << "55";
ss.setf(fmt, std::ios::basefield);
ss >> lVal;

// for reading binary 
bitset<numeric_limits<size_t>::digits> bt("101010");
lVal = bt.to_ulong();

...

3. Output

There's no more magic now. Just use the manipulators for streams again, for writing this time. For binaries, just call the to_string() method.

Using the code

Just use the code in a common C++ class, as demonstrated below:

#include "LiteralConverter.h"

...

// 1. declare an object
CLiteralConverter lc;

// 2. assign the input string, using the default delimiters(",; :h")
lc.SetString("5 aa bb cc dd 2", CLiteralConverter::HEX);

// 3. get the converted string, using the default delimiters("; ")
string s;
s = lc.GetString(CLiteralConverter::DEC);
s = lc.GetString(CLiteralConverter::OCT);
s = lc.GetString(CLiteralConverter::BIN);
s = lc.GetString(CLiteralConverter::HEX);

// or: get the value for customizeed treatment
vector<size_t> vl;
lc.GetValue(vl);

...

CLiteralConverter Functions

Set the Original Data

Call these functions to set the original data, the format and the delimiters:

  • void SetString(const string& s, _FORMAT_ format, const string& sDelim = ",; :h")
  • void SetString(ifstream& f, _FORMAT_ formatsDelim, const string& sDelim = ",; :h")

    The first prototype accepts a std::string type string as input, while the second one accepts a std::ifstream. Please make sure f has been correctly initialised before being passed in. It is recommended that f.is_open() be asserted before calling SetString(). format can be CLiteralConverter::HEX, CLiteralConverter::DEC, CLiteralConverter::OCT, or CLiteralConverter::BIN.

Get the Converted Data

Call this function to get the original data, the format and the delimiters:

  • string GetString(_FORMAT_ format, const string& sDelim = "; ")

    This function returns the converted data string, given the desired format. format can be CLiteralConverter::HEX, CLiteralConverter::DEC,CLiteralConverter::OCT, or CLiteralConverter::BIN.

Some more specific variants are also provided:

  • string GetDec(const string& sDelim = "; ") to get a decimal output.
  • string GetHex(const string& sDelim = "; ") to get a hexadecimal output.
  • string GetOct(const string& sDelim = "; ") to get a Octal output.
  • string GetBin(const string& sDelim = "; ") to get a binary output.

In the case of customized operation on the data, GetValue(vector<size_t>& vValue) can be called to get the stored values.

Enjoy!

References

  1. Free peer-reviewed portable C++ source libraries.
  2. CKCSideBannerWnd: An MFC Banner control that can add a professional looking feel to most windows... by Peter Mares. This class is used to make the the demo application look nicer. Thanks Peter.

Revision History

  1. Veriosn 1.0, 2005-05-13
    • - First release
  2. Version 1.1, 2009-08-19
    • - Fixed an overflow bug with long type, use size_t instead.
      - Added a console demo application
      - Updated demo applications to VS2008

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here