my open-source plain C code中,我使用以下简单结构从字符串缓冲区读取和解析数据:

typedef struct lts_LoadState
{
  const unsigned char * pos;
  size_t unread;
} lts_LoadState;

使用this simple API访问该缓冲区:
/* Initialize buffer */
void ltsLS_init(lts_LoadState * ls,const unsigned char * data, size_t len);

/* Do we have something to read? (Actually a macro.) */
BOOL ltsLS_good(ls);

/* How much do we have to read? (Actually a macro.) */
size_t ltsLS_unread(ls);

/* Eat given number of characters, return pointer to beginning of eaten data */
const unsigned char * ltsLS_eat(lts_LoadState * ls, size_t len);

注意:可以用ltsLS_unread替换return (ltsLS_good(ls)) ? SIZE_MAX : 0,而不会破坏当前的实现。

此代码用于load some data in a custom format from a string buffer。 (This可能是一个更好的例子。)

现在,我需要不是从字符串缓冲区而是从FILE指针加载数据。

我不喜欢复制粘贴实现,而希望重用现有代码。 (当然,我可以重构/适应它。)

这是C++中的一本教科书,但是如何在普通C中做到这一点而又不会增加运行时开销?

这是一个使用lts_LoadState API且不被复制粘贴的示例函数(但是可以更改,以支持字符串缓冲区和FILE *):
static int ltsLS_readline(
    lts_LoadState * ls,
    const unsigned char ** dest,
    size_t * len
  )
{
  const unsigned char * origin = ls->pos;
  unsigned char last = 0;
  size_t read = 0;

  while (ltsLS_good(ls))
  {
    if (ltsLS_unread(ls) > 0)
    {
      unsigned char b = *ls->pos; /* OK, this should be ltsLS_eat_char macro. */
      ++ls->pos;
      --ls->unread;

      if (b == '\n')
      {
        *dest = origin;
        *len = (last == '\r') ? read - 1 : read;

        return LUATEXTS_ESUCCESS;
      }

      last = b;
      ++read;
    }
    else
    {
      ls->unread = 0;
      ls->pos = NULL;
    }
  }

  return LUATEXTS_ECLIPPED;
}

最佳答案

听起来好像您想要函数变量,您可以将其作为参数传递。 C可以做到,但是语法不是很漂亮。

可能会有一些运行时开销,但不是很多。

How do you pass a function as a parameter in C?

关于c - 在普通C语言中应用鸭式打字,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10001570/

10-11 04:28