views:

92

answers:

4

I'm trying to port some of my c++ code into c. I have the following construct

class reader{
private:
FILE *fp;
alot_of_data data;//updated by read_until() method
public:
  reader(const char*filename)
  read_until(some conditional dependent on the contents of the file, and the arg supplied)
}

Im then instantiating hundreds of these object and iterate over them using several 'read_until()' for each file until allfiles is at eof.

I'm failing to see any clever way to do this in c, the only solution I can come up with is making an array of FILE pointers, and do the same with all the private member data from my class.

But this seems very messy, can I implement the functionality of my class as a function pointer, or anything better, I think I'm missing a fundamental design pattern?

The files are way to big to have all in memory, so reading everything from every file is not feasible Thanks

A: 

You could always create a structure to hold all the related information, and then loop over that... Just an idea... (I think C supports structures - it's been a while...)

Martin Milan
+1  A: 

The principle of information hiding is the same, regardless of the language you use. Just move the stuff you want to hide into the source file:

// reader.h
typedef struct reader reader;

reader* new_reader(const char*filename);
void read_until(reader*, ...);

// reader.c

struct reader {
    FILE *fp;
    alot_of_data data;//updated by read_until() method
};

reader *new_reader(const char*filename) { ... }
void read_until(reader*, ...) { ... }
Marcelo Cantos
Why double pointer `reader**` in `read_until()`?
pajton
I had the impression `read_until` was supposed to work on a bunch of files, but on re-reading that looks wrong. I've fixed it.
Marcelo Cantos
@Marcelo Ok, taking an array or `readers` made sense too.
pajton
+1  A: 

The easiest way is to just convert the data into a struct:

struct reader
{
  FILE *file;
  alot_of_data data;
};

Then define ordinary functions, that take a struct reader as their first argument:

int reader_construct(struct reader *r, const char *filename)
{
  if((r->file = fopen(filename, "rt")) == NULL)
    return 0;
  /* do other inits */
  return 1;
}

and the reader function becomes:

int read_until(struct reader *r, arguments)
{
  /* lots of interesting code */
}

Then just have an array of structures, call reader_construct() on them and then do the read_until() calls as required.

You could of course opt for a more dynamic constructor, that returns the "object":

struct reader * reader_new(const char *filename)
{
  struct reader *r = malloc(sizeof *r);
  if(r == NULL)
    return NULL;
  if(reader_construct(r, filename))
    return r;
  return NULL;
}
unwind
+1  A: 

You create an abstract data type:

typedef struct {
  FILE *fp;
  alot_of_data data;//updated by read_until() method
} reader;

void init_reader(reader* that, const char* filename);
void read_until(reader* that, some conditional dependent on the contents of the file, and the arg supplied)

Then you can create and use objects of this type just as with objects of the class, except that, instead of obj.func(), you write func(&obj):

reader r;
init_reader(&r, "blah.txt");
read_until(&r, /* ... */);
sbi