Una interfaz de lector que consume ARCHIVOS y caracteres * en C

Estoy modificando un analizador que he heredado que actualmente solo lee desde ARCHIVO * a través de lectura. Ahora tiene el requisito de poder extraer datos de las constantes char * también para que se pueda analizar el texto en línea dentro de las cadenas en C.

He analizado la posibilidad de proporcionar una interfaz simple tanto en forma de “lectores” para que pueda proporcionar un lector de archivos y un lector de caracteres desde el que el analizador pueda capturar caracteres. Por ejemplo:

// Inputs const char *str = "stringToParse"; FILE *f = fopen(...); // Creating a reader. Each reader stores a function ptr to a destructor // which closes the file if required and an internal state object. Reader *r = FileReader(f); // -or- Reader *r = CharReader(str); // Start parsing --------------------------- // Inside the parser, repeated calls to: int error = ReadBytes(&buf /* target buf */, &nRead /* n read out */, maxBytes /* max to read */); // End parsing ----------------------------- CloseReader(&r); // calls destructor, free's state, self 

Me gustaría mantener esto realmente simple. ¿Hay otras formas obvias de lograr esto usando menos infraestructura que me he perdido?

Nota: He simplificado esto considerablemente de lo que hay para resaltar las inquietudes de la interfaz de progtwigción. En realidad, utiliza wchar_t internamente y un montón de cosas de encoding y es un poco como un nido de ratas que desentrañar al mismo tiempo.


Gracias a todos los que contestaron. La respuesta más limpia es usar fmemopen. He proporcionado un ejemplo completo a continuación:

 #include  #include  void dump(FILE *f) { char c; while ((c = fgetc(f)) != EOF) putchar(c); } int main(int argc, char *argv[]) { /* open string */ const char str[] = "Hello string!\n"; FILE *fstr = fmemopen(&str, strlen(str), "r"); /* open file */ FILE *ffile = fopen("hello.file", "r"); /* dump each to stdout */ dump(ffile); dump(fstr); /* clean up */ fclose(ffile); fclose(fstr); } 

Ni siquiera necesita un CharReader en su infraestructura. En su lugar, lo siguiente debería funcionar cuando los búferes de memoria tienen el mismo diseño que los archivos:

 const char *str = "stringToParse"; FILE *f = fmemopen(str, strlen(str), "r"); Reader *r = FileReader(f); // use FileReader to read from string... 

Es bastante difícil tener una API más simple que “create_resource”, “use_resource”, “free_resource”. Así que la abstracción en cuanto a esto parece bastante razonable.

Supongo que & nRead es el argumento del lector de flujo para ReadBytes? Si no es así, ¿cómo indica ReadBytes qué secuencia desea procesar? (Si esta es la única transmisión que va a procesar, puede dejar el recurso sin nombre y simplemente referirse a la única en ReadBytes. Pero en ese caso, Reader y CloseReader tampoco necesitan devolver la entidad de la transmisión).