Libscws - 0.0.1 C API 说明

$Id: README.usage,v 1.1 2007/06/08 06:25:35 hightman Exp $

本说明由 hightman 编写于 2007.06.08
网页版地址：http://www.hightman.cn/bbs/viewthread.php?tid=37

0. 概述
Libscws 代码是当前 SCWS(简易中文分词) 算法使用C语言编写的链接库，目前仅基于 Unix 族的操作系统，可能必须适当修改才能运行在 Windows 平台中。这套 scws 库没有外部扩展依赖，代码力争简洁高效，针对分词词典组织上做了一些优化。
除分词外，由于分词词库采用的是自行设计的xdb 和 xtree 结构，故本库函数也可以用以 XDB 和 XTree 数据存取（另行介绍）。
1. 数据类型 （仅列出API中需要关注的部分）
·scws 操作句柄，几乎所有的 API 函数都使用到它，不应尝试拷贝 scws_st 结构，不保证这类拷贝结果会有用。
typedef struct
{
  xdict_t d;
  rule_t r;
  unsigned char *mblen;
  unsigned int mode;
  unsigned char *txt;
  int len;
  int off;
  scws_res_t res0;
  scws_res_t res1;
  word_t **wmap;
  struct scws_zchar *zmap;
} scws_st, *scws_t;
struct scws_zchar
{
  int start;
  int end;
};
注：xdict_t 和 rule_t 分别是词典和规则集的指针，可判断其是否为 NULL 来判断加载的成功与失败。
·scws 系列结果集，每次 scws 返回的分词结果的数量都是不定的，直到返回结果为 NULL 才表示这次分词过程结束，
  这是一个单链表结构。
typedef struct scws_result *scws_res_t;
struct scws_result
{
  int off;
  float idf;
  unsigned char len;
  char attr[3];
  scws_res_t next;
};
·scws 高频关键词统计集，简称＂词表集＂，这是 scws 中统计调用时返回用的结构，也是一个单链表结构。

typedef struct scws_topword *scws_top_t;
struct scws_topword
{
  char *word;
  float weight;
  short times;
  char attr[2];
  scws_top_t next;
};

2. 函数说明
·scws_t scws_new();
描述：分配或初始化与scws系列操作的 scws_st 对象。该函数将自动分配、初始化、并返回新对象的指针。通过调用 scws_free() 来释放该对象。
返回值：初始化的 scws_st * （即 scws_t） 句柄。如果无足够内存以分配新的对象，返回NULL。
错误：在内存不足的情况下，返回NULL。
·void scws_free(scws_t s);
描述：释放由 scws_new() 返回的 scws 操作句柄及对象内容，同时也会释放已经加载的词典和规则。
返回值：无
错误：无
·void scws_set_charset(scws_t s, const char *cs);
描述：设定当前 scws 所使用的字符集，目前仅支持 gbk 和 utf-8 两种字符集。参数 cs 描述的是新指定的字符集。若无此调用则系统缺省使用gbk字符集，指定字符集时 cs 参数的大小写不敏感。
返回值：无
错误：若指定的字符集不存在，则会自动使用 gbk 字符集替代。
·void scws_set_dict(scws_t s, const char *fpath, int mode);
描述：设定当前 scws 操作所有的词典文件。参数 fpath 描述的是词典的文件路径，词典格式是 XDB 格式。
参数 mode 有2种值，分别为宏定义的：SCWS_XDICT_XDB （这表示直接读取 xdb 文件）、SCWS_XDICT_MEM （这表示将 xdb 文件全部加载到内存中，以 XTree 结构存放）。具体用哪种方式需要根据自己的实际应用来决定。当使用本库做为 daemon server 时应当使用 mem 方式，当只是 embed 调用时应该使用 xdb 方式，将 xdb 文件加载进内存不仅占用了比较多的内存，而且也需要一定的时间（35万条数据约需要0.3~0.5秒左右）。
若此前 scws 句柄已经加载过词典，则此调用会先释放已经加载的词典。
返回值：无

错误： 如果加载失败，scws_t 结构中的 d 元素为 NULL，即通过  s->d == NULL 与否来判断加载失败或成功。

·void scws_set_rule(scws_t s, const char *fpath);
描述：设定规则集文件。参数 fpath 是规则集文件的路径。若此前 scws 句柄已经加载过规则集，则此调用会先释放已经加载的规则集。规则集定义了一些新词自动识别规则，包括常见的人名、地区、数字年代等。规则编写方法另行参考其它部分。
返回值：无
错误：加载失败，scws_t 结构中的 r 元素为 NULL，即通过 s->r == NULL 与否来判断加载的失败与成功。

·void scws_set_ignore(scws_t s, int yes);
描述：设定分词执行过程中是否忽略所有的标点等特殊符号（不会忽略\r和\n）。参数 yes 为 1 表示忽略，为0表示不忽略，缺省情况为不忽略。
返回值：无
错误：无

·void scws_set_multi(scws_t s, int yes);
描述：设定分词执行时是否执行针对长词复合切分。（例如：中国人->中国+人+中国人）。参数 yes 为 1表示复合分，为0表示相反。缺省不复合分词。
返回值：无
错误：无
·void scws_set_debug(scws_t s, int yes);
描述：设定分词时对于疑难多路径综合分词时，是否打印出各条路径的情况。注意，打印使用的是 fprintf(stderr, ... 故，这项功能不要随便使用，仅在命令行嵌入式调用时可以使用，参见例子中的 cmd.c 。当库函数编译选项中加入 -DLIBSCWS_QUIET 时此项不生效。（参见 php 扩展，PHP扩展里就是加入此项）
返回值：无
错误：无

·void scws_send_text(scws_t s, const char *text, int len);
描述：设定要切分的文本数据，text 指定该串文本的起始位置，而 len 表示这段文本的长度。该函数可安全用于二进制数据，不会因为字符串中包括 \0 而停止切分。这个函数应该在 scws_get_result 和 scws_get_tops 之前调用。
返回值：无
错误：无。
注：scws结构内部维护着该字符串的指针和相应的偏移及长度，故连续调用的话后者会覆盖前者的设定；不应在多次 scws_get_result 循环中调用 scws_send_text()。

·scws_res_t scws_get_result(scws_t s);
描述：取回一系列分词结果集，该分词结果必须调用 scws_free_result() 释放，传入链表头指针。
返回值：返回的是结果集链表的头部指针。该函数必须循环调用，当返回值为 NULL 时表示分词结束。
错误：无

·void scws_free_result(scws_res_t result);
描述：根据结果集的链表头释放结果集
返回值：无
错误：无

·scws_top_t scws_get_tops(scws_t s, int limit, char *xattr);
描述：返回指定的关键词表统计集，系统会自动根据词语出现的次数及其 idf 值计算排名。参数 limit 指定取回数据的最大条数，若传入值为0或负数，则自动重设为10。参数 xattr 用来描述要排除或参与的统计词汇词性，多个词性之间用逗号隔开。当以~开头时表示统计结果中不包含这些词性，否则表示必须包含，传入 NULL 表示统计全部词性。
返回值：返回词表集链表的头指针，该词表集必须调用 scws_free_tops 释放
错误：无

·void scws_free_tops(scws_top_t tops);
描述：根据词表集的链表头释放词表集
返回值：无
错误：无
3. 使用实例
一个简单的分词实例：
#include <scws.h>
#include <stdlib.h>
main()
{
scws_t s;
scws_res_t res, cur;
char *text = "Hello, 我名字叫李那曲是一个中国人, 我有时买Q币来玩, 我还听说过C#语言";

if (!(s = scws_new())) {
printf("error, can't init the scws_t!\n");
exit(-1);
}
scws_set_charset(s, "gbk");
scws_set_dict(s, "/path/to/dict.xdb", SCWS_XDICT_XDB);
scws_set_rule(s, "/path/to/rules.ini");

scws_send_text(s, text, strlen(text));
while (res = cur = scws_get_result(s))
{
while (cur != NULL)
{
printf("Word: %.*s/%s (IDF = %4.2f)\n", cur->len, text+cur->off, cur->attr, cur->idf);
cur = cur->next;
}
scws_free_result(res);
}

scws_free(s);
}

假设 libscws 被放在 /path/to/libcws/ 中编译
编译：gcc -o test -I/path/to/libscws -L/path/to/libcws test.c -lscws
完整的实例请参见相关的源码：scwsc 命仅行分词代码。
