Introduction
Converting data when you are working with strings is always not very interesting, and may be quite long.
Here is some code that will help you with converting strings into any other format:
- string to integer (int, long, short, byte, char,...)
- string to floating numbers (float, double)
- string to boolean (bool)
- string to special integers (dec, hex, oct, or bin)
And, all this is done with only one function!!
Background
I'm working with an XML database which provides me string data which are in different formats (integers, float, hexadecimal numbers, octal numbers). So I decided to create some code that will automate casts without having to to change the function each time I'm reading new data (a function for integers, another for float,...).
This could be useful to avoid multiple functions and simplify code maintenance.
Using the code
Here is a function that reads data from any source (here, it is just hard coded to simplify the example) and runs the converting function. The function is based on the return type so that the cast is transparent to the user. See in the main function how this is finally used, and it is very simple to understand and use.
CStringAutoCast ReadDataFromFile(CStringAutoCast::E_format format= CStringAutoCast::kDec)
{
const std::string csReadFromFile = "230";
return CStringAutoCast(csReadFromFile, format);
}
int main(int argc, char* argv[])
{
int a = ReadDataFromFile();
float b = ReadDataFromFile();
unsigned char c = ReadDataFromFile();
long d = ReadDataFromFile(CStringAutoCast::kOct);
unsigned long e = ReadDataFromFile(CStringAutoCast::kHex);
std::string f = ReadDataFromFile();
return 0;
}
How it works
This is a simple class that implements different operators, so just assign an instance of the class to an int
or a double
, and it will automatically call the right operator.
Header
#ifndef __STRING_AUTO_CAST_H__
#define __STRING_AUTO_CAST_H__
class CStringAutoCast
{
public:
typedef enum
{
kDec = 0,
kBin = 1,
kHex = 2,
kOct = 3
}E_format;
public:
CStringAutoCast(const std::string & input, E_format format = kDec);
virtual ~CStringAutoCast();
operator bool() const;
operator std::string() const;
operator unsigned int() const;
operator int() const;
operator unsigned short() const;
operator short() const;
operator unsigned long() const;
operator long() const;
operator unsigned char() const;
operator char() const;
operator float() const;
protected:
std::string m_data;
E_format m_format;
};
#endif // !defined __STRING_AUTO_CAST_H__
Implementation
The code is very simple, and there is no difficulty to understand the code (except templates for beginners).
#include "stdafx.h"
#include "StringAutoCast.h"
#define USE_BOOST_LIBS
#ifdef USE_BOOST_LIBS
#include "boost/lexical_cast.hpp"
#endif
template <class T>
T _internal_integer_convert(const std::string & m_data,
const CStringAutoCast::E_format m_format)
{
T ret;
switch(m_format)
{
case CStringAutoCast::kDec:
sscanf(m_data.c_str(), "%d", &ret);
break;
case CStringAutoCast::kBin:
sscanf(m_data.c_str(), "%b", &ret);
break;
case CStringAutoCast::kHex:
sscanf(m_data.c_str(), "%x", &ret);
break;
case CStringAutoCast::kOct:
sscanf(m_data.c_str(), "%o", &ret);
break;
}
return ret;
}
CStringAutoCast::CStringAutoCast(const std::string & input,
E_format format):
m_format(format),m_data(input)
{
}
CStringAutoCast::~CStringAutoCast()
{
}
CStringAutoCast::operator bool() const
{
return ( _strnicmp(m_data.c_str(), "true", 4)==0 ||
_strnicmp(m_data.c_str(), "1", 1)==0);
}
CStringAutoCast::operator std::string() const
{
return m_data;
}
CStringAutoCast::operator unsigned int() const
{
return _internal_integer_convert<unsigned int>(m_data, m_format);
}
CStringAutoCast::operator int() const
{
return _internal_integer_convert<int>(m_data, m_format);
}
CStringAutoCast::operator unsigned short() const
{
return _internal_integer_convert<unsigned short>(m_data, m_format);
}
CStringAutoCast::operator short() const
{
return _internal_integer_convert<short>(m_data, m_format);
}
CStringAutoCast::operator unsigned long() const
{
return _internal_integer_convert<unsigned long>(m_data, m_format);
}
CStringAutoCast::operator long() const
{
return _internal_integer_convert<long>(m_data, m_format);
}
CStringAutoCast::operator unsigned char() const
{
return _internal_integer_convert<unsigned char>(m_data, m_format);
}
CStringAutoCast::operator char() const
{
return _internal_integer_convert<char>(m_data, m_format);
}
CStringAutoCast::operator float() const
{
#ifdef USE_BOOST_LIBS
return boost::lexical_cast<float>(m_data);
#else
float ret;
sscanf(m_data.c_str(), "%f", &ret);
return ret;
#endif
}
Points of interest
I think this code is very easy to use and may be very useful in projects.
Actually, the code does not really manage error statements (in case the input string does not match the expected format); this is just a basic example.
History
- August, 20 2007: First code version.