Um, Q is in C.
First, a little helper function:
1 2 3 4 5
|
char* zero( char* p )
{
if (p) *p = '\0';
return p;
}
|
Now you can write a function to read your file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
bool read_vars( const char* filename )
{
char s[ 128 ];
char* p;
FILE* fp = filename ? fopen( filename, "r" ) : stdin;
if (!fp) return false;
// while we can read a line from the file
while (fgets( s, sizeof( s ), fp ))
{
zero( strchr( s, '\n' ) );
// split the line into name and value
if (zero( p = strchr( '=' ) )) ++p;
char* name = trim( s );
char* value = p ? trim( p ) : NULL;
// add the name,value to your dictionary
...
}
fclose( fp );
return true;
}
|
You can find a variety of ways to trim a string in the FAQ:
http://www.cplusplus.com/faq/sequences/strings/trim/#c. I would use the inplace/advance versions for this particular piece of code.
I don't know how you plan to implement your dictionary, but the current grid thing you are attempting to do won’t work well. A very simple alternative is to use an array of struct:
1 2 3 4 5 6 7 8 9 10
|
typedef struct
{
char* name;
char* value;
}
pair;
const int NVARS = 100;
pair vars[ NVARS ];
int nvars = 0;
|
Thereafter, to add a (name,value) pair to your dictionary, just append it.
1 2 3 4 5 6 7 8 9
|
void add_var( const char* name, const char* value )
{
if (nvars < NVARS)
{
vars[ nvars ].name = strdup( name );
vars[ nvars ].value = strdup( value );
nvars += 1;
}
}
|
Be sure to clean up properly when destroying the dictionary:
1 2 3 4 5 6 7 8 9
|
void free_vars()
{
for (int n = 0; n < nvars; n++)
{
free( vars[ n ].name );
free( vars[ n ].value );
}
nvars = 0;
}
|
Having a handy way to find a pair is also useful:
1 2 3 4 5 6 7 8 9 10
|
// Find an item in the dictionary.
// Returns nvars if not found.
int find_var( const char* name )
{
int n;
while (n < nvars)
if (strcmp( name, vars[ n ].name ) == 0) break;
else n += 1;
return n;
}
|
The only limitation is the fixed size of an array. You could make it a dynamic array, and resize when necessary. Another easy option would be to use a linked list.
Whatever you choose, I would make an ADT to handle it. A good one might look like:
1 2 3 4 5 6 7 8 9
|
bool dictionary_create( dictionary* );
void dictionary_destroy( dictionary* );
size_t dictionary_size( dictionary* );
bool dictionary_set( dictionary*, const char* key, const char* value );
const char* dictionary_get( dictionary*, const char* key );
void dictionary_unset( dictionary*, const char* key );
dictionary_iterator dictionary_first( dictionary* );
dictionary_iterator dictionary_next( dictionary_iterator );
|
It could be used like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
int main()
{
dictionary dict;
if (!dictionary_create( &dict )) return 1;
dictionary_set( &dict, "birds", "7" );
dictionary_set( &dict, "cats", "9" );
dictionary_set( &dict, "humans", "2" );
// The humans go out to lunch
dictionary_unset( &dict, "humans" );
printf( "There are %lu items in the dictionary:\n", (unsigned long)dictionary_size( &dict ) );
dictionary_iterator iterator = dictionary_first( &dict );
while (iterator)
{
printf( " %s = %s\n", iterator->key, iterator->value );
iterator = dictionary_next( iterator );
}
printf( "Oops, that was too many cats. Let's fix that:"
dictionary_set( &dict, "cats", "3" );
printf( " cats = %s\n", dictionary_get( &dict, "cats" ) );
dictionary_destroy( &dict );
|
The output:
There are 2 items in the dictionary:
cats = 9
birds = 7
Oops, that was too many cats. Let's fix that:
cats = 3
|
Implementing these kinds of functions is really easy. More importantly, it makes
using your dictionary
so much easier.
Hope this helps.