0

我正在修改我继承的解析器,该解析器目前仅通过读取从 FILE* 读取。它现在还需要能够从 char* 常量中提取数据,以便可以解析 C 字符串中的内联文本。

我已经研究过以“阅读器”的形式为两者提供一个简单的接口,这样您就可以提供一个文件阅读器和一个字符阅读器,解析器可以从中获取字符。例如:

// 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

我想保持这个非常简单。有没有其他明显的方法可以使用我错过的更少的基础设施来实现这一目标?

注意:为了突出编程接口问题,我已经大大简化了这一点。它实际上在内部使用 wchar_t 和一堆编码的东西,有点像老鼠窝,我将同时解开它。


感谢所有回答的人。最干净的答案是使用 fmemopen。我在下面提供了一个完整的例子:

#include <stdio.h>
#include <string.h>

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);
}
4

2 回答 2

3

你甚至不需要CharReader在你的基础设施中。相反,当内存缓冲区与文件具有相同的布局时,以下应该工作:

const char *str = "stringToParse";
FILE *f = fmemopen(str, strlen(str), "r");

Reader *r = FileReader(f);

// use FileReader to read from string...
于 2013-06-23T08:54:39.797 回答
0

很难拥有比“create_resource”、“use_resource”、“free_resource”更简单的 API。所以从抽象的角度来看,这似乎很合理。

我假设 &nRead 是 ReadBytes 的流阅读器参数?如果不是,ReadBytes 如何指示它要处理的流?(如果这是您要处理的唯一流,那么您可以不命名资源并简单地引用 ReadBytes 中唯一的资源。但在这种情况下,Reader 和 CloseReader 也不需要返回流实体)。

于 2013-06-23T08:55:34.927 回答