在C中读取文件和字符串数组

时间:2016-05-06 11:10:13

标签: c file

我有一个函数void* producer(void* param),它被传递给多个POSIX线程,其目标是读取文件的每一行 {{1}的每一行} array 并处理它们。

问题:如何使此功能优雅地适应这两种可能的输入? (我想第一个是文件的文件名或string (char*))。

到目前为止,该函数只能读取文件,这里是代码:

FILE*

1 个答案:

答案 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中的任何代码。