reading data from txt file.

Hey everyone, I'm trying to create a basic program that reads data from a txt file
that looks like this:
/* data.txt */
var1 = value1
var2 = value2
var3 = value3
var4 = value4
/************/

and store these variables and their values into an array of chars.
here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

int main(int argc, char *argv[])
{
char *grid = (char*)malloc(9 * 9);

FILE* f_read = fopen("data.txt", "r");

int i = 0;

char tempGrid[128];
while (fscanf(f_read, "%c", &tempGrid[i]))
{
// what should i add here?
i++;
}

free(grid);
fclose(f_read);

return 0;
}
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <fstream>
#include <string>
#include <map>
using namespace std;

//======================================================================

string trim( string s, string junk )
{
   int i = s.find_first_not_of( junk );
   if ( i == string::npos ) return "";

   int j = s.find_last_not_of( junk );
   return s.substr( i, j - i + 1 );
}

//======================================================================

int main()
{
   string filename = "data.txt";
   map<string,string> myThings;        // this will hold variable name and value
   string name, value;

   ifstream in( filename );
   while ( getline( in, name, '=' ) )  // try reading up to '=' (which is then discarded)
   {
      getline( in, value );   if ( !in ) break;

      name  = trim( name , " " );           // remove start and end blanks if required
      value = trim( value, " " );

      myThings[name] = value;          // assign to an associative container (map)
   }
   in.close();

   cout << "Read " << myThings.size() << " items, as follows:\n";
   cout << "Name\tvalue\n";
   for ( auto e : myThings ) cout << e.first << '\t' << e.second << '\n';
}

//====================================================================== 


Read 4 items, as follows:
Name	value
var1	value1
var2	value2
var3	value3
var4	value4

thank you @lastchance. but i am trying to get the vars and values using fscanf or fread.
I know it would be complicated a little but i have to do it.
Last edited on
Why?
university...
Does your file actually contain two strings separated by an equals sign, or does it contain a "name" followed by an equal sign and then a numeric value?



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.
Last edited on
Yeah that's what i'm talking about, you got skills.
Last edited on
Nah, people aren’t taught how to use C properly, so it looks like magic when you see it. But, you’re welcome. Keep on learning! :O)
Topic archived. No new replies allowed.