Hi,

I have data coming over a socket that looks like this

(h)(int,char,float,int,char)(/h)(d)(2,a,1.32,45,d)(3,d,3.45,32,a)(/d)

the datatype of the data arriving is dynamic and is only known when the header is received.I then have to create corresponding vectors(stl) to store the data. In this case, 2 int,2 char and one float vector. I dont know how to initialize in such a case.Can someone help me out?

Edited 6 Years Ago by AutoC: n/a

I think the easiest was is to use a union then create a vector of those unions.
In the structure below, member "kind" is an int that tells what data type is valid -- one of the defines listed.

enum DataKind {unknown = 0, chartype,shorttype,inttype,longtype, floattype};

struct data
{
   DataKind  kind;
   union type
   {
      char cType;
      short sType;
      int   iType;
      long  lType;
      float fType;
      // etc for each type you want to support
   } DataType;
   data() {kind = unknown;}
};

int main()
{
   vecto<data> items;
}

Edited 6 Years Ago by Ancient Dragon: n/a

Parse the type string (int, char, float etc.) and the data in text form into strings.
If the possible types are known before hand, a simple if/else if construct would do the job.

#include <string>
#include <vector>
#include <boost/lexical_cast.hpp>
#include <stdexcept>

template< typename T >
void do_push_back( std::vector<T>& v, const std::string& text_data )
{ v.push_back( boost::lexical_cast<T>(text_data) ) ; }

void push_back( const std::string& type_name,
                const std::string& text_data,
                std::vector<int>& int_vec,
                std::vector<char>& char_vec,
                std::vector<float>& float_vec )
                      throw( boost::bad_lexical_cast, std::invalid_argument )
{
    if( type_name == "int" ) do_push_back( int_vec, text_data ) ;
    else if( type_name == "char" ) do_push_back( char_vec, text_data ) ;
    else if( type_name == "float" ) do_push_back( float_vec, text_data ) ;
    else throw std::invalid_argument( "unknown type" ) ;
}

I think the easiest was is to use a union then create a vector of those unions.
In the structure below, member "kind" is an int that tells what data type is valid -- one of the defines listed.

enum DataKind {unknown = 0, chartype,shorttype,inttype,longtype, floattype};

struct data
{
   DataKind  kind;
   union type
   {
      char cType;
      short sType;
      int   iType;
      long  lType;
      float fType;
      // etc for each type you want to support
   } DataType;
   data() {kind = unknown;}
};

int main()
{
   vecto<data> items;
}

This is awesome! thanks. But how do I use each type? I'm doing a switch on the incoming type and if it is one from the list how do i assign them?

This is an example of one way to use it. main() declares a vector, but makes no use of it.

#include <vector>
#include <iostream>
using std::vector;
using std::cout;

enum DataKind {unknown = 0, chartype,shorttype,inttype,longtype};

struct data
{
   DataKind kind;
   union type
   {
      char cType;
      short sType;
      int   iType;
      long  lType;
      // etc for each type you want to support
   } DataType;
   data() {kind = unknown;}
};

void filldata(data& d, char value)
{
    d.DataType.cType = value;
    d.kind = chartype;
}

void filldata(data& d, short value)
{
    d.DataType.sType = value;
    d.kind = shorttype;
}
void filldata(data& d, int value)
{
    d.DataType.iType = value;
    d.kind = inttype;
}
void filldata(data& d, long value)
{
    d.DataType.lType = value;
    d.kind = longtype;
}

int main()
{
    vector<data> items;
    data d;
    char c = 'A';
    short s = 123;
    int i = 234;
    long l = 456;
    filldata(d, c);
    filldata(d, s);
    filldata(d, i);
    filldata(d, l);

    // display the value
    switch(d.kind)
    {
    case chartype: cout << d.DataType.cType << '\n'; break;
    case shorttype: cout << d.DataType.sType << '\n'; break;
    case inttype: cout << d.DataType.iType << '\n'; break;
    }
	return 0;
}
This article has been dead for over six months. Start a new discussion instead.