Dynamically assigning data-types

This is a discussion on Dynamically assigning data-types within the C Programming forums, part of the General Programming Boards category; I need to work out a way of storing in a structure the data from a table whose number of ...

  1. #1
    Registered User
    Join Date
    Oct 2002
    Posts
    98

    Dynamically assigning data-types

    I need to work out a way of storing in a structure the data from a table whose number of columns and column datatypes are unknown. As a first step, I'm trying to work out a way of storing data in variables when you don't know what the datatype of the variable is, and I've attempted it like this...

    Code:
    #include <stdio.h>
    
    #define _INT 99
    #define _CHAR 98
    #define _FLOAT 97
    
    int main( int argc,
              char *argv[] )
    {
    /*
    ** Variable declarations
    */
      void *data_value = NULL;
    
      int the_int = 1;
      char the_char = 'a';
      float the_float = 1.5;
    
      int i = 0;
    
    /*
    ** Program code
    */
      printf( "\n\n" );
    
      for( i = 99 ; i > 0 ; i-- )
      {
        switch( i )
        {
          case( _INT ) : /* Allocate an integer memory space to the void pointer */
                         data_value = ( int * ) malloc( sizeof(int));
                         data_value = the_int;
                         printf( "Case( INT ) : %d\n", *data_value );
                         break;
          case( _CHAR ) : /* Allocate a char memory space to the void pointer */
                          data_value = ( char * ) malloc( sizeof(char));
                          data_value = the_char;
                          printf( "Case( CHAR ) : %c\n", *data_value );
                          break;
          case( _FLOAT ) : /* Allocate a float memory space to the void pointer */
                           data_value = ( float * ) malloc( sizeof(float));
                           printf( "Case( FLOAT ) : %f\n", *data_value );
                           free( data_value );
                           break;
          default : printf( "\n\n" );
                    exit( 0 );
        }
      }
    }
    This code won't compile because of the lines which assign values to the newly malloc'd void pointer areas. I haven't tried anything like this before, and could do with some tips.

    Also, am I re-inventing the wheel here..? Is there a better way of doing this.

    Thanks.
    There is no such thing as a humble opinion

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You can't dereference a void pointer. The typical way to represent a variable that can have multiple data types is to use a union. Here is some rough sample code.
    Code:
    typedef enum { DT_INT, DT_CHAR, DT_FLOAT } DATA_TYPE;
    
    typedef struct {
    	DATA_TYPE dt;
    	union {
    	  int   intVal;
    	  char  charVal;
    	  float floatVal;
    	} data;
    } MULTI;
    Code:
        switch( i )
        {
          case( _INT ) : /* Allocate an integer memory space to the void pointer */
                         my_multi.dt = DT_INT;
                         my_multi.data.intVal = the_int;
                         break;
          case( _CHAR ) : /* Allocate a char memory space to the void pointer */
                         my_multi.dt = DT_CHAR;
                         my_multi.data.charVal = the_char;
                         break;
          case( _FLOAT ) : /* Allocate a float memory space to the void pointer */
                         my_multi.dt = DT_FLOAT;
                         my_multi.data.floatVal = the_float;
                         break;
          default : printf( "\n\n" );
                    exit( 0 );
        }
    Code:
    void PrintMulti(MULTI* pMulti)
    {
    	switch(pMulti->dt)
    	{
    		case DT_INT:
    			printf("%d\n", pMulti->data.intVal);
    			break;
    
    		case DT_CHAR:
    			printf("%c\n", pMulti->data.charVal);
    			break;
    
    		case DT_FLOAT:
    			printf("%.2f\n", pMulti->data.floatVal);
    			break;
    
    		default:
    			printf("Unknown data type!\n");
    	}
    }
    For an example of a more complex multiple data type check out the Windows VARIANT.

  3. #3
    Registered User
    Join Date
    Oct 2002
    Posts
    98
    Thanks for that. I guess for storing the table data, I'll just create an array of MULTI's, as large as the number of columns in the table. Cheers.
    There is no such thing as a humble opinion

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Actually you can dereference a void pointer. You just have to do it correctly.

    Here's something I was toying with a while ago in response to a topic about void pointers, somewhat similar to this one, but I never got around to posting it.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main( void )
    {
        const char *specifier[] = { "%c", "%d", "%f", "%s" };
        size_t size[] = { 1, sizeof( int ), sizeof( float ), BUFSIZ };
        int x;
        void *data = NULL;
    
        printf(
            "1) Read a single character.\n"
            "2) Read a single integer.\n"
            "3) Read a floating point number.\n"
            "4) Read in a string.\n\n"
            "Your choice: "
        );
    
    
        x = getchar();
        if( x < '1' || x > '4' )
            return !!printf( "Next time try following the rules.\n" );
    
        x -= '1';
    
        while( getchar() != '\n' );
    
        if( (data = malloc( size[ x ] )) )
        {            
            printf( "Enter your data now: " );
            fflush( stdout );
    
            if( scanf( specifier[ x ], data ) == 1 )
            {
                printf( "You entered \'" );
                switch( x )
                {
                    case 0: printf( specifier[ x ], *((char*)data) ); break;
                    case 1: printf( specifier[ x ], *((int*)data) ); break;
                    case 2: printf( specifier[ x ], *((float*)data) ); break;
                    case 3: printf( specifier[ x ], (char*)data ); break;
                }
                printf( "\'!\n" );
            }
            free( data );
        }
    
        return 0;
    }
    The string input is done the lazy way, so fix it yourself if you don't like it

    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Extending basic data types.
    By nempo in forum C++ Programming
    Replies: 23
    Last Post: 09-25-2007, 03:28 PM
  2. HUGE fps jump
    By DavidP in forum Game Programming
    Replies: 23
    Last Post: 07-01-2004, 10:36 AM
  3. can't insert data into my B-Tree class structure
    By daluu in forum C++ Programming
    Replies: 0
    Last Post: 12-05-2002, 05:03 PM
  4. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM
  5. Using enumerated data types
    By SXO in forum C++ Programming
    Replies: 7
    Last Post: 09-04-2001, 06:26 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21