我有一个函数void* producer(void* param)
,它被传递给多个POSIX线程,其目标是读取文件的每一行或 {{1}的每一行} array 并处理它们。
问题:如何使此功能优雅地适应这两种可能的输入? (我想第一个是文件的文件名或string (char*)
)。
到目前为止,该函数只能读取文件,这里是代码:
FILE*
答案 0 :(得分:2)
提供一个知道如何根据其内容生成下一行的结构。例如(未经测试):
typedef struct {
FILE *fp;
const char *str;
} Source;
Source *source_new_from_file(const char *filename)
{
Source *ret = malloc(sizeof(Source));
if (!ret)
return NULL;
ret->fp = fopen(filename, "rb");
if (!ret->fp)
return NULL;
ret->str = NULL;
return ret;
}
Source *source_new_from_str(const char *str)
{
Source *ret = malloc(sizeof(Source));
if (!ret)
return NULL;
ret->fp = NULL;
ret->str = str;
return ret;
}
bool source_read_line(Source *s, char *dest, size_t destsize)
{
if (s->fp)
return fgets(dest, destsize, s->fp) != NULL;
const char *newline = strchr(s->str, '\n');
if (!newline)
// handle trailing line without newline, like fgets does
newline = s->str + strlen(s->str);
if (newline == s->str)
return false; // no more data
size_t linelen = newline - s->str;
if (linelen > destsize - 1)
linelen = destsize - 1;
memcpy(dest, s->str, linelen);
dest[linelen + 1] = '\0';
s->str = newline;
return true;
}
// ...
void* producer(void* param)
{
Source *source = param;
char line[256];
while (source_read_line(source, line, sizeof line)) {
processLine(line);
}
return NULL;
}
使用此代码,您可以将任何类型的来源传递给producer
。即使出现了一种新的源(例如,数据库查询的结果集,或者“行”被编码为XML元素的XML文档),您也只能通过扩展{{1}来实现新功能。 },而不更改source_read_line
中的任何代码。