Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

A class that converts string data to any format

1.67/5 (5 votes)
19 Aug 2007CPOL2 min read 1   306  
Converts a string to any format you want!!!

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.

C++
/**
 * @brief Read data from a file and automatically convert it to return data type
 * 
 * @param format specify the format of read data
 * (only for inter-like data (int, short, char, long,...)
 *
 * @return CStringAutoCast 
 */
CStringAutoCast ReadDataFromFile(CStringAutoCast::E_format format= CStringAutoCast::kDec)
{
    /*
        here put some code that read a file (txt, xml or whatever you want) and 
        extract    data as std::string csReadFromFile
    */
    const std::string csReadFromFile = "230";

    //now converts read string
    return CStringAutoCast(csReadFromFile, format);
}

/**
 * @brief main function of project
 * 
 * @param argc number of arguments
 * @param argv list of arguments
 *
 * @return int program exit code
 */
int main(int argc, char* argv[])
{
    int a        = ReadDataFromFile();
    float b        = ReadDataFromFile();
    unsigned char c = ReadDataFromFile();
    //specifies that the string read is in Octal format
    long d        = ReadDataFromFile(CStringAutoCast::kOct);
    //specifies that the string read is in Hexadecimal format
    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

C++
#ifndef __STRING_AUTO_CAST_H__
#define __STRING_AUTO_CAST_H__

/**
 * @brief Class that make string data automatically converted to numeric data
 *
 * @author Le Sourcie
 */
class CStringAutoCast
{
public:
    /**
     * E_format: enumeration of type of input data
     */
    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:
    /**
     * m_data: data to convert
     */
    std::string m_data;
    /**
     * m_format: format of data to convert from
     */
    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).

C++
#include "stdafx.h"
#include "StringAutoCast.h"

//comment this line if you cannot compile with boost librairies
#define USE_BOOST_LIBS

#ifdef USE_BOOST_LIBS
#include "boost/lexical_cast.hpp"
#endif

//////////////////////////////////////////////////////////////////////
// Global functions
//////////////////////////////////////////////////////////////////////
/**
 * @brief convert a string from a E_format (hex, dec,
 * oct or bin) to an integer-like return type
 *
 * @param m_data string data to convert
 * @param m_format format of data
 *
 * @return data converted to template type
 */
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;
}


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

/**
 * @brief Constructor
 *
 * @param input data to convert
 * @param format format of data
 *
 */
CStringAutoCast::CStringAutoCast(const std::string & input, 
                                 E_format format/*=kDec*/): 
                                 m_format(format),m_data(input)
{
}

/**
 * @brief   Destructor
 *
 *
 */
CStringAutoCast::~CStringAutoCast()
{
}


/**
 * @brief operator for bool
 *
 *
 * @return CStringAutoCast data as bool
 */
CStringAutoCast::operator bool() const
{
    return ( _strnicmp(m_data.c_str(), "true", 4)==0 || 
             _strnicmp(m_data.c_str(), "1", 1)==0);
}

/**
 * @brief operator for std::string
 *
 *
 * @return CStringAutoCast data as std::string (no conversion in this case)
 */
CStringAutoCast::operator std::string() const
{
    return m_data;
}

/**
 * @brief operator for unsigned int
 *
 *
 * @return CStringAutoCast data as unsigned int
 */
CStringAutoCast::operator unsigned int() const
{
    return _internal_integer_convert<unsigned int>(m_data, m_format);
}

/**
 * @brief operator for int
 *
 *
 * @return CStringAutoCast data as int
 */
CStringAutoCast::operator int() const
{
    return _internal_integer_convert<int>(m_data, m_format);
}

/**
 * @brief operator for unsigned short
 *
 *
 * @return CStringAutoCast data as unsigned short
 */
CStringAutoCast::operator unsigned short() const
{
    return _internal_integer_convert<unsigned short>(m_data, m_format);
}

/**
 * @brief operator for short
 *
 *
 * @return CStringAutoCast data as short
 */
CStringAutoCast::operator short() const
{
    return _internal_integer_convert<short>(m_data, m_format);
}

/**
 * @brief operator for unsigned long
 *
 *
 * @return CStringAutoCast data as unsigned long
 */
CStringAutoCast::operator unsigned long() const
{
    return _internal_integer_convert<unsigned long>(m_data, m_format);
}

/**
 * @brief operator for long
 *
 *
 * @return CStringAutoCast data as long
 */
CStringAutoCast::operator long() const
{
    return _internal_integer_convert<long>(m_data, m_format);
}

/**
 * @brief operator for unsigned char
 *
 *
 * @return CStringAutoCast data as unsigned char
 */
CStringAutoCast::operator unsigned char() const
{
    return _internal_integer_convert<unsigned char>(m_data, m_format);
}

/**
 * @brief operator for char
 *
 *
 * @return CStringAutoCast data as char
 */
CStringAutoCast::operator char() const
{
    return _internal_integer_convert<char>(m_data, m_format);
}

/**
 * @brief operator for float
 *
 *
 * @return CStringAutoCast data as float
 */
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)