欢迎访问 Lu程序设计

Lu系统扩展动态库LuSystem

目 录

1 什么是LuSystem
2 lu表
sys::luu | 整数常量，用在函数new[sys::luu,... ...]中，申请luu表对象。该对象的基本类型为lu，扩展类型为luu。
sys::luu[...] | 生成 luu表对象并初始化。该对象的基本类型为lu，扩展类型为luu。
new | 该函数是重载函数，但直接调用了lu的new函数。用于申请luu表对象，该对象的基本类型为lu，扩展类型为luu。
+ | 重载运算符+。连接两个luu表，或者将一个简单数加到luu表的前面或后面。
len | 该函数是重载函数，但直接调用了lu的len函数。返回luu表的长度。
o | 该函数是重载函数。输出luu表的内容。运行错误：1：不可识别对象。
oset | 该函数是重载函数，但直接调用了lu的oset函数。设a是一个luu表，则执行形如a[i]=2的赋值语句时将调用该函数。
oget | 该函数是重载函数，但直接调用了lu的oget函数。设a是一个luu表，则执行形如a[i]的语句时将调用该函数。
3 字符串
ASCII字符串 | 单字节字符串。通常先转换为双字节字符串，操作后，再将结果转换为单字节字符串。
sys::astring | 整数常量，用在函数new[sys::astring,... ...]中，申请astring对象（ASCII字符串）。函数new将调用函数astr以生成astring对象。
sys::astr | 用法1：astr[k]。k为一个整数，返回一个k字节长的单字节字符串，初始化为一个空串。 用法2：astr[str]。str为一个双字节字符串，转换为单字节字符串并返回该串。 运行错误：1：参数非法；2：内存错误。
sys::ustr | 用法：astr[str]。str为一个单字节字符串，转换为双字节字符串并返回该串。运行错误：1：参数非法；2：内存错误。
o | 该函数是重载函数。仅提示信息： ***ASCII字符串须先用函数ustr转换为Unicode字符串后才能显示***
Unicode字符串 | 双字节字符串。Lu系统默认字符串。
sys::String | 整数常量，用在函数new[sys::String,... ...]中，申请String对象。该对象的基本类型为string，扩展类型为String。
sys::String["abc"] | 生成 String对象并用一个字符串初始化 ，实际上是生成了该字符串的一个副本。该对象的基本类型为string，扩展类型为String。 运行错误：1：不可识别的初始化参数。
new | 该函数是重载函数，但直接调用了string的new函数。用于申请String对象，该对象的基本类型为string，扩展类型为String。
+ | 重载运算符+，但直接调用了string的+函数。连接两个String。
len | 该函数是重载函数，但直接调用了string的len函数。返回String的缓冲区长度。strlen函数返回一个字符串的长度。
o | 该函数是重载函数。输出String的内容。运行错误：1：不可识别对象。
oset | 该函数是重载函数，但直接调用了string的oset函数。设a是一个String，则执行形如a[i]=2的赋值语句时将调用该函数。
oget | 该函数是重载函数，但直接调用了string的oget函数。设a是一个String，则执行形如a[i]的语句时将调用该函数。
sys::strlen[str] | 返回字符串str的长度。len(str)返回字符串str的缓冲区大小。运行错误：1：不可识别对象。
sys::strcpy[str1,str2] | 复制字符串str2到str1。当str1是动态字符串时，如果缓冲区不够用，会自动增加缓冲区。该函数不生成新的字符串 ，仍返回str1。 运行错误：1：参数非法；2：内存错误；3：静态缓冲区不够用。
sys::strcat[str1,str2] | 将字符串str2连接到str1的后面。当str1是动态字符串时，如果缓冲区不够用，会自动增加缓冲区。该函数不生成新的字符串 ，仍返回str1。 运行错误：1：参数非法；2：内存错误；3：静态缓冲区不够用。
sys::substr[str,begin,end] | 返回字符串str的子字符串，begin和end指定了子字符串的位置。如果begin或end为-1，或者大于字符串长度，取字符串的最后一个字符位置；此时，若begin>end，取end和begin之间字符串的反序字符串。运行错误：1：参数非法；2：内存错误。 例子1：substr["abcdefg",-1,3]，结果：gfed 例子2：substr["abcdefg",3,-1]，结果：defg
sys::strchr[str,c] | 在字符串str中定位首次出现的字符c（整数），返回c在str中的下标（相对偏移量），失败时返回-1。运行错误：1：参数非法。
sys::strrchr[str,c] | 在字符串str中定位最后出现的字符c（整数），返回c在str中的下标（相对偏移量），失败时返回-1。运行错误：1：参数非法。
sys::strcmp[str1,str2] | 按字母顺序，对字符串进行比较。若str1<str2，返回值<0；若str1=str2，返回值=0；若str1>str2，返回值>0。运行错误：1：参数非法。
sys::strpbrk[str1,str2] | 在字符串str1中定位字符集str2中首次出现的某个字符，返回这个字符在str1中的下标（相对偏移量），失败时返回-1。运行错误：1：参数非法。
sys::strspn[str1,str2] | 在字符串str1中定位首次出现的不包含在字符集str2中的某个字符，返回这个字符在str1中的下标（相对偏移量），失败时返回-1。运行错误：1：参数非法。
sys::strstr[str1,str2,begin,end] | 在字符串str1中查找子串str2，返回子串在str1中的位置（相对偏移量），失败时返回-1。begin和end指定了查找位置；若缺省end，则从begin位置开始查找；若begin和end都缺省，则查找整个字符串。运行错误：1： 参数个数非法；2：参数非法。
sys::strtok[str1,str2] | 在字符串str1（包含分隔符和记号）中提取记号，str2是包含分隔符的字符串，返回一个luu对象，luu对象包含了所有提取的记号，失败时返回nil。 运行错误：1：参数非法。 例子：sys::strtok["one,two three , four*five", ", *"].o[];
sys::strlwr[str] | 将字符串str转换为小写，仍返回该字符串。运行错误：1：参数非法。
sys::strupr[str] | 将字符串str转换为大写，仍返回该字符串。运行错误：1：参数非法。
sys::strset[str,ch,begin,end] | 将字符串str中从begin～end的内容设置为字符ch。若缺省begin和end，则设置整个内容；若仅缺省end，则设置从begin开始的内容。仍返回该字符串。运行错误：1：参数个数非法；2：参数非法。
sys::strrev[str] | 反转字符串str中的字符顺序，仍返回该字符串。运行错误：1：参数非法。
sys::strrep[str,oldstr,newsyt,start,ntimes] | 将字符串str中的子串oldstr替换为newstr，返回替换后的字符串。start为查找替换的开始位置，缺省为从头开始替换。ntimes 指定进行替换的次数，缺省表示替换所有匹配。运行错误：1：参数个数非法；2：参数非法 ；3：内存错误。
sys::strdate[] | 把日期拷贝到一个字符串中并返回该字符串，失败时返回nil。
sys::strtime[] | 把时间拷贝到一个字符串中并返回该字符串，失败时返回nil。
Regex正则表达式 | 使用 DEELX 正则表达式引擎。请参考：DEELX正则引擎文档，或者 DEELX正则引擎网站。
sys::ComRegex | 编译正则表达式文本。
sys::MatchExact | 验证传入的文本是否刚好匹配正则表达式。
sys::Match | 从文本中查找匹配符合表达式的子字符串。
sys::GetNamedGroupNumber | 通过命名分组名，返回命名分组编号。
sys::PrepareMatch | 初始化上下文对象，准备从文本中查找匹配符合表达式的子字符串。
sys::Replace | 文本替换操作。
sys::IsMatched | 获取是否匹配成功。
sys::GetStart | 获取匹配到的子字符串开始位置。
sys::GetEnd | 获取匹配到的子字符串结束位置。
sys::GetGroupStart | 获取分组开始位置。
sys::GetGroupEnd | 获取分组结束位置。
sys::MaxGroupNumber | 获取正则表达式最大捕获组编号。
4 字典
sys::dict | 整数常量，用在函数new[sys::dict,... ...]中，申请字典对象。
sys::dict["a":2, "b":8, ...] | 生成字典对象并初始化。运行错误：1：字典元素不匹配；2：字典元素的键应为字符串；3：内存错误。
new | 该函数是重载函数，用于申请字典对象。一般用法：new[sys::dict, "a":2, "b":8, ... ...]
o | 该函数是重载函数。输出字典的内容。运行错误：1：不可识别对象。
oset | 该函数是重载函数。设a是一个字典，则执行形如a."b"=2的赋值语句时将调用该函数。运行错误：1：参数太多或者太少；2：不可识别对象；3：非法的字符串；4：内存错误。
oget | 该函数是重载函数。设a是一个字典，则执行形如a."b"的语句时将调用该函数，获得字典元素的值。运行错误：1：参数太多或者太少；2：不可识别对象；3：非法的字符串。
len | 该函数是重载函数。设a是一个字典，len(a)求a的所有元素数目。
sys::dict_oset[p:"a",2] | 设置字典p的元素"a"的值为2。运行错误：1：参数太多或者太少；2：不可识别对象；3：非法的字符串；4：内存错误。
sys::dict_oget[p:"a"] | 获得字典p的元素"a"的值。运行错误：1：参数太多或者太少；2：不可识别对象；3：非法的字符串。
sys::dict_del[p:"a","bc",...] | 删除字典p的元素"a","bc",...。运行错误：1：参数太少；2：不可识别对象；3：非法的字符串。
sys::dict_clear[p] | 清空字典p的所有元素。运行错误：1：不可识别对象。
sys::dict_reverse[p] | 字典反序。
5 结构
sys::struct | 整数常量，用在函数new[sys::struct,... ...]中，申请结构对象。
sys::struct[#a, #b:8, ...] | 生成结构对象并初始化 ，结构成员必须以#开头。运行错误：1：非法的结构成员；2：结构成员重名。
new | 该函数是重载函数，用于申请结构对象。一般用法：new[sys::struct, #a, #b:8, ...]
o | 该函数是重载函数。输出结构的内容。运行错误：1：不可识别对象。
oset | 该函数是重载函数。设a是一个结构，则执行形如a.#b=2的赋值语句时将调用该函数。运行错误：1：参数太少；2：不可识别对象或成员；3：没有找到成员。
oget | 该函数是重载函数。设a是一个结构，则执行形如a.#b的语句时将调用该函数，获得结构成员的值。运行错误：1：参数太少；2：不可识别对象或成员；3：没有找到成员。
len | 该函数是重载函数。设a是一个结构，len(a)求a的所有成员数目。
copy | 该函数是重载函数。设a和b是结构，copy(a)求a的副本，copy(a,b)复制b的内容到a（执行a.=b时将自动调用该函数），copy(a: #ab,2, #b:8, ...)求a的副本并进行初始化，初始化参数要成对。运行错误：1：不可识别对象 ；2：对象结构不相同；3：非法的成员标识；4：没有找到成员；5：参数不匹配。
set | 该函数是重载函数，设置结构的成员。设a是一个结构，a.set(#ab,2, #b:8, ...)设置a的成员，注意参数要成对。运行错误：1：参数太少；2：不可识别对象 ；3：非法的成员标识；4：没有找到成员；5：参数不匹配。
sys::struct_oset[p,#b : 2] | 设置结构p的成员#b的值为2。运行错误：1：参数太少；2：不可识别对象或成员；3：没有找到成员。
sys::struct_oget[p,#b] | 获得结构p的成员#b的值。运行错误：1：参数太少；2：不可识别对象或成员；3：没有找到成员。
6 类
sys::class | 整数常量，用在函数new[sys::class,... ...]中，申请类定义。
sys::obj | 整数常量，用在函数new[sys::obj,pclass,... ...]中，申请类对象，其中pclass是类定义。
sys::class | 创建类定义。
sys::obj | 创建类对象。
sys::class_handle(#AA) | 根据类名称得到类句柄，该句柄可用在函数obj中创建类对象。
new | 该函数是重载函数，用于申请类定义及类对象。
o | 该函数是重载函数。输出类定义及类对象的内容。运行错误：1：不可识别对象；2：找不到类定义。
oset | 该函数是重载函数。设a是一个类对象，则执行形如a.#b=2的赋值语句时将调用该函数。运行错误：1：参数太少；2：不可识别成员标识；3：不可识别对象标识；4：没有找到类成员；5：不可识别的结构对象；6：没有找到结构成员；7：不可识别数据类型；8：成员函数参数不匹配；9：不可更改基类对象。
oget | 该函数是重载函数。设a是一个类对象，则执行形如a.#b的语句时将调用该函数，获得类成员的值。运行错误：1：参数太少；2：不可识别成员标识；3： 不可识别对象标识；4：没有找到类成员；5：不可识别的结构对象；6：没有找到结构成员；7：不可识别数据类型；8：成员函数参数不匹配。
copy | 该函数是重载函数。设a和b是对象，copy(a,b)复制b的内容到a，执行a.=b时将自动调用该函数。运行错误：1： 参数太多或者太少；2：不可识别对象；3：对象结构不相同；4：对象的成员函数#__copy__参数不是2个；5：没有找到成员函数#__copy__的句柄。
sys::obj_oset[p,#b : 2] | 设置对象p的成员#b的值为2。运行错误：1：参数太少；2：不可识别成员标识；3：不可识别对象标识；4：没有找到类成员；5：不可识别的结构对象；6：没有找到结构成员；7：不可识别数据类型；8：成员函数参数不匹配；9：不可更改基类对象。
sys::obj_oget[p,#b] | 获得对象p的成员#b的值。运行错误：1：参数太少；2：不可识别成员标识；3： 不可识别对象标识；4：没有找到类成员；5：不可识别的结构对象；6：没有找到结构成员；7：不可识别数据类型；8：成员函数参数不匹配。
sys::obj_method | 调用类对象的方法。
7 文件系统函数
sys::file | 整数常量，用在函数new[sys::file,... ...]中，打开一个文件（将调用函数 sys::fopen 打开一个文件）。
sys::fopen | 打开文件。
sys::fclose | 关闭文件。
sys::fwrite | 写文件。
sys::fread | 读文件。
sys::fseek | 设置文件指针的位置。
sys::feof | 判断是否到文件尾。
sys::fflush | 刷新一个打开的流，将缓冲区中的内容写入文件。
sys::ftell | 获取文件指针位置。
sys::rewind | 把文件指针设置回文件的起始位置。
sys::readtxt["aa.txt"] | 该函数以文本方式打开文件，并将内容读到一个字符串，该函数返回这个字符串，出错时返回nil。运行错误：1：参数不可识别。
sys::writetxt["aa.txt",str] | 该函数以文本方式创建或打开文件（如果打开一个文件，则原文件将被覆盖），并将字符串str的内容写入文件，该函数返回写入字符的个数，出错时返回nil。运行错误：1：参数不可识别。
8 格式化输入输出函数
sys::printf | 格式化输出到标准设备。
sys::sprintf | 格式化输出到字符串。
sys::fprintf | 格式化输出到文件。
sys::sscanf | 从字符串格式化输入。
sys::fscanf | 从文件格式化输入。
sys::setlocale | 设置当前地域的各种要素。
9 时间
sys::tm | 整数常量，用在函数new[sys::tm,... ...]中，申请存放时间的tm结构对象。
new | 该函数是重载函数，用于申请tm结构对象。一般用法：new[sys::tm,time()]。申请存放时间的tm结构对象 ，初始化参数 time()可以缺省。 将直接调用函数tm生成对象。参考函数tm的说明。
o | 该函数是重载函数。输出tm结构的内容。运行错误：1：不可识别对象。
oset | 该函数是重载函数。设a是一个tm结构，则执行形如a.tm_sec=2的赋值语句时将调用该函数。运行错误：1：参数太多或者太少；2：不可识别对象 。
oget | 该函数是重载函数。设a是一个tm结构，则执行形如a.tm_sec的语句时将调用该函数，获得tm成员的值。运行错误：1：参数太多或者太少；2：不可识别 参数。
sys::tm[time()] | 申请存放时间的tm结构对象（经过时区转换的UTC时间），初始化参数 time()可以缺省。tm结构成员：tm_sec（秒，正常范围0-59， 但允许至61）；tm_min（分钟，0-59）；tm_hour（小时， 0-23）；tm_mday（日，即一个月中的第几天，1-31）；tm_mon（月， 从一月算起，0-11）；tm_year（年， 从1900至今已经多少年）；tm_wday（星期，一周中的第几天， 从星期日算起，0-6）；tm_yday（从今年1月1日到目前的天数，范围0-365）；tm_isdst（夏令时标识符，实行夏令时的时候，tm_isdst为正；不实行夏令时的进候，tm_isdst为0；不了解情况时，tm_isdst为负）。
sys::time() | 取得从1970年1月1日至今的秒数（整数）。
sys::difftime(time1, time2) | 返回两个时间相差的秒数。time1, time2为整数；返回值为实数。
sys::mktime(t) | 将tm结构的时间转换为从1970年至今的秒数（整数）。
sys::gmtime(t) | 将整数表示的时间转换为没有经过时区转换的UTC时间，是一个tm结构对象。
sys::localtime(t) | 将整数表示的时间转换为经过时区转换的UTC时间，是一个tm结构对象。
10 其他
sys::null | 空指针常量。
sys::vtype(a) | 返回a的扩展类型。
sys::isnil(a) | 判断一个数据是否是nil，若是返回true，否则返回false。
sys::rearray(a) | 数组维数反序，该函数用于在Lu数组（C数组格式）和Fortran数组之间进行转换。a是一个实数或整数数组。例如三维数组a[2,3,5]，调用该函数后，将成为a[5,3,2]。运行错误：1：非法的数组指针。
sys::lufun | 以Lu表的元素为自变量进行函数调用。
sys::ShellExecute | 执行外部程序。
sys::SetCurrentDirectory(a) | 设置当前目录，a是一个字符串。设置成功仍返回a，否则返回nil。
sys::GetCurrentDirectory(a) | 获得当前目录，a是一个字符串，用于存放当前目录。获取成功仍返回a，否则返回nil。

1 什么是LuSystem [返回页首]

LuSystem32.dll是一个Lu系统扩展动态库，包含一些增强Lu系统功能的函数、对系统内置类型的扩展以及一些新增数据类型等等。LuSystem不仅是对Lu系统的扩充，更在于演示Lu是极易扩充其功能的脚本，很少有脚本允许用户能方便地添加像字典、结构、类等高级的数据结构，但Lu允许，而且实现这些很容易，因而，LuSystem也是编程用户极佳的练手工具。

主要的数据类型有：

luu：系统内置类型lu表的扩展类型。

String：系统内置类型字符串string的扩展类型。使用Unicode字符串。 可以使用正则表达式。

dict：字典。

struct：结构。

class：类。

file：文件类型。

在LuSystem中的函数是通过二级函数命名空间“sys”输出的，所有函数均具有类似“sys::lufun(...)”的格式。使用!!!using("sys");可简化LuSystem中的函数访问。

LuSystem目前还不完善，主要用来演示Lu系统的可扩充性，但一些实用的功能或函数会不断添加进来， 任何人也可以根据需要添加或改进函数的功能，欢迎大家给出各种改进的建议！

LuSystem 的源代码是开放的，源代码下载：http://www.forcal.net/xiazai/lu1/lu1code.rar

2 lu表 [返回页首]

luu是系统内置类型lu表的扩展类型。luu表是一个可直接存取的线性表，可以存放若干任意的Lu数据。

（1）新建luu表

> !!!using("sys");
> new[luu,5 : 1,1.2,"abc"].o[]; //用函数new生成luu表，长度为5，有三个初始化数据。函数o用于输出luu表。

用函数luu生成luu表更为方便：

> !!!using("sys");
> luu[1+2i,1.2,"abc"].o[]; //用函数luu生成luu表，长度为3，有三个初始化数据。函数o用于输出luu表。

（2）元素存取

> !!!using("sys");
> main(:a)= a=luu[1+2i,1.2,"abc"], a[1]=a[2]+"luuuu", o[a];

（3）luu表连接：可用加号+连接两个luu表，或者将一个简单数加到luu表的前面或后面

> !!!using("sys");
> main(:a,b)= a=luu[1,1,1], b=luu[2,2], o[a+b, 3+a, a+3];

3 字符串 [返回页首]

String是系统内置类型字符串string的扩展类型。

> （1）生成String

> !!!using("sys");
> new[String,5 : "abc"].o[]; //用函数new生成String，长度为5， 并用一个字符串进行初始化。函数o用于输出String，并返回输出的字符数目。

> 用函数String生成String更为方便：实际上该函数生成了原字符串的一个副本。

> !!!using("sys");
> String["abc"].o[]; //用函数String生成String，必须用一个字符串作为初始化数据。

> 注意：函数strcpy将原字符串复制到目标字符串，但不会返回一个新串。

> !!!using("sys");
> main(:a)= a=String[""], strcpy[a,"abc"], o[a];

> （2）元素存取：可直接对字符串做更改。

> !!!using("sys");
> main1(:a)= a=String["abc"], a[1]=a[2]+1, o[a]; //动态字符串
> main2(:a)= a="abc", a[1]=a[2]+1, o[a]; //静态字符串

> （3）String缓冲区大小和长度

> !!!using("sys");
> main(:a)= a=new[String,5 : "abc"], o{"字符串缓冲区=",len(a)," 字符串长度=",strlen(a),"\r\n"};

> （4）String连接：用加号+连接两个字符串，返回一个新串。

> !!!using("sys");
> o{String["abc"]+String["def"]};
> o{String["abc"]+"def"};

> （5）String连接：用函数strcat连接两个字符串，不返回新串。

> !!!using("sys");
> main(:me)=
> me=String["abc"], printf["%s\r\n",me], //输出me
> strcat(me,"def"), printf["%s\r\n",me]; //输出me

> （6）大小写互换：用自定义函数实现

> !!!using("sys");
> Swapcase(str:i,k,ch,a,z,A,Z)=
> k="azAZ", a=k[0], z=k[1], A=k[2], Z=k[3], //获得字符azAZ的ASCII值
> k=strlen[str], i=0,
> while{i<k, ch=str(i),
> which{ch>=a & ch<=z : str(i)=ch-a+A,
> ch>=A & ch<=Z : str(i)=ch-A+a,
> ch},
> i++
> },
> str;
> Swapcase["abc 88 啊啊 DEF"].o[];

> （7）格式化字符串，用sprintf函数实现

> !!!using("sys");
> main(:a,b,k,i,s)=
> a=String[""], sprintf[a,"%20s","abc"], o[a,"\r\n"], //固定长度，右对齐，左边不够用空格补齐
> a=String[""], sprintf[a,"%-20s","abc"], o[a,"\r\n"], //固定长度，左对齐，右边不够用空格补齐
> a=String[""], b="abc", k=[20-strlen(b)]/2, s=new[String,k+1], i=0, while{i<k,s[i++]=32},
> sprintf[a,"%s%s%s",s,b,s], o[a,"\r\n"]; //固定长度，中间对齐，两边不够用空格补齐

> （8）去字符串两边空格

> !!!using("sys");
> main(:a,i,j,k)= a=[" asd 啊啊 def "], i=strspn(a," \r\n\t"), strrev(a), j=strlen(a)-strspn(a," \r\n\t")-1, strrev(a), o{substr[a,i,j]};

> （9）是否以start开头

> !!!using("sys");
> main(:a)= a=[" start 啊啊 def "], strspn(a," \r\n\t")==strstr(a,"start");

> （10）是否全小写

> !!!using("sys");
> main(:a)= a=[" start wsx def "], strspn(a,"abcdefghijklmnopqrstuvwxyz \r\n\t")<0;

[返回页首] sys::ComRegex(pattern,flags)：编译正则表达式文本

pattern：字符串，正则表达式。
flags：表达式匹配模式。支持的匹配模式有：sys::reIgnoreCase, sys::reSingleline, sys::reMultiline, sys::reGlobal, sys::reRightToLeft, sys::reExtended 这 6 种模式以及它们的组合，或者使用缺省的sys::reNoFlag模式。可以缺省该参数，缺省值为sys::reNoFlag。详细说明如下：

sys::reIgnoreCase ：匹配时忽略大小写。默认情况下，正则表达式是要区分大小写的。不管是否指定忽略大小写模式，字符类，比如 [A-Z] 是要区分大小写的。
sys::reSingleline ：使小数点 "." 可以匹配包含换行符（\n）在内的任意字符。默认情况下，小数点只匹配换行符以外的任意字符，不匹配换行符。
sys::reMultiline ：使 ^ 符号除了能够匹配字符串开始位置外，还能匹配换行符（\n）之后的位置；使 $ 符号除了能够匹配字符串结束位置外，还能匹配换行符之前的位置。默认情况下， ^ 符号只能匹配字符串开始位置， $ 符号只能匹配字符串结束位置。sys::reSingleline 和 sys::reMultiline 虽然听起来相互矛盾，但却是作用在不同的地方。因此它们是可以组合使用的。在指定了 sys::reMultiline 之后，如果需要仅匹配字符串开始和结束位置，可以使用 \A 和 \Z。
sys::reGlobal ：使 \G 可以用来匹配本次查找匹配的开始位置，对于连续的匹配来说，也就是上次匹配的结束位置。默认情况下， \G 没有作用。在进行替换操作（Replace）时，不管是否指定 sys::reGlobal 模式，都可以进行所有的替换。是否指定 sys::reGlobal 模式只是对 \G 起作用。如果希望进行有限次数的替换，可在替换操作时指定替换次数。
sys::reRightToLeft ：从右向左的进行匹配。从被匹配字符串的结束位置向前进行查找匹配，同时，在表达式中也是右侧的表达式先进行匹配。表达式的写法仍然按原来的习惯：匹配次数修饰符（*, +, {n}, ……）仍然位于被修饰部分的右侧而不是左侧；^ 仍然匹配文本开始而不是文本结束；(?=xxx) 仍然是正向与搜索（向右预搜索），而不是向左；分组（group）编号仍然是从左向右进行编号；等等。不管整个表达式是否指定了 sys::reRightToLeft 模式，"反向预搜索（反向零宽度断言）" 内的表达式始终采用 sys::reRightToLeft 模式。
sys::reExtended ：使 DEELX 忽略表达式中的空白字符，并且把从 # 开始到该行行末的内容视为注释。默认情况下，正则表达式中的空格，换行等字符将可以匹配相应的字符。指定了 sys::reExtended 模式后，如果要在正则表达式中表示空白字符比如空格符号（space）时，应该用 \x20 表示，如果要在表达式中表示 # 符号，应该用 \# 表示。不管是否指定了 sys::reExtended 模式，括号内以 ?# 号开始时，比如(?# xxx )，那么这一对括号以及包含的内容都始终作为注释而被忽略。

返回值：pattern。出错时返回nil。

说明：任何一个正则表达式对象，都需要先用该函数编译正则表达式文本后才能使用。

运行错误：1：参数个数非法；2：参数非法。

例子：判断一个字符串是否全由数字组成

> !!!using["sys"]; //使用命名空间sys
> main()=
> {
> ComRegex(@"\d+"), //编译正则表达式文本
> MatchExact("12345"), //验证是否刚好匹配
> which{
> IsMatched() : printf{"\r\nyes!\r\n"}, //匹配成功输出yes
> printf{"\r\nno!\r\n"} //匹配失败输出no
> }
> };

[返回页首] sys::MatchExact(str)：验证传入的文本是否刚好匹配正则表达式

str：进行匹配的字符串。

返回值：str。

说明：所谓刚好匹配，就是要求正则表达式从文本开始位置刚好匹配到文本结束位置。匹配结果可通过函数sys::IsMatched 获取。

运行错误：1：非法的字符串。

例子

[返回页首] sys::Match(... ...)：从文本中查找匹配符合表达式的子字符串

格式1：sys::Match()：使用上下文对象，从上次匹配结束位置或者初始化位置开始查找匹配。上下文对象需要先使用函数sys::PrepareMatch进行初始化。
格式2：sys::Match(str)：Match 方法未指定开始位置，则根据当前匹配模式是否是 sys::reRightToLeft 模式决定开始位置：如果是普通模式，则从 0 开始，向右查找；如果是 sys::reRightToLeft 模式，则从字符串结束位置开始，向左查找。
格式3：sys::Match(str,start)：Match 方法指定了开始位置，则从指定位置开始查找。

str：进行匹配的字符串。
start：开始查找匹配的位置。

返回值：str。

说明：匹配结果可通过函数sys::IsMatched 等函数获取。

运行错误：1：参数个数非法；2：参数非法。

例子1：Match格式1：在一段 C++ 源代码文本中，查找注释

> !!!using["sys"];
> main(:str)=
> {
> str=new(string,"int a; /* a */"), //申请字符串，存放源代码
> ComRegex(@"/\*((?!\*/).)*(\*/)?|//([^\x0A-\x0D\\]|\\.)*"), //编译正则表达式文本
> PrepareMatch(str), //匹配准备
> Match(), //匹配子字符串
> which{
> IsMatched() : printf{"\r\nfound:%s\r\n",substr[str,GetStart(),GetEnd()-1]}, //匹配成功输出匹配结果
> printf{"\r\nnot found!\r\n"} //匹配失败输出 not found!
> }
> };

例子2：Match格式2：在一段 C++ 源代码文本中，查找注释

> !!!using["sys"];
> main(:str)=
> {
> str=new(string,"int a; /* a */"), //申请字符串，存放源代码
> ComRegex(@"/\*((?!\*/).)*(\*/)?|//([^\x0A-\x0D\\]|\\.)*"), //编译正则表达式文本
> Match(str), //匹配子字符串
> which{
> IsMatched() : printf{"\r\nfound:%s\r\n",substr[str,GetStart(),GetEnd()-1]}, //匹配成功输出匹配结果
> printf{"\r\nnot found!\r\n"} //匹配失败输出 not found!
> }
> };

例子3：列举一段文本中所有的带小数的数字

> !!!using["sys"];
> main(:str,result)=
> {
> str=new(string,"12.5, a1.1, 0.123, 178"), //申请字符串，存放文本
> ComRegex(@"\b\d+\.\d+"), //编译正则表达式文本
> PrepareMatch(str), //匹配准备
> Match(), //匹配子字符串
> while{IsMatched(), //匹配成功输出匹配结果
> printf{"%s\r\n",substr[str,GetStart(),GetEnd()-1]},
> Match() //匹配子字符串
> }
> };

[返回页首] sys::GetNamedGroupNumber(GroupName)：通过命名分组名，返回命名分组编号

GroupName：字符串，命名分组名。

返回值：命名分组编号。

运行错误：1：非法的字符串。

[返回页首] sys::PrepareMatch(tstring,start)：初始化上下文对象，准备从文本中查找匹配符合表达式的子字符串

tstring：进行匹配的字符串。
start：开始查找的起始位置。可以缺省该参数，此时根据当前匹配模式是否是 sys::reRightToLeft 模式决定开始位置：如果是普通模式，则从 0 开始，向右查找；如果是 sys::reRightToLeft 模式，则从结束位置开始，向左查找。

返回值：tstring。

运行错误：1：参数个数非法；2：参数非法。

例子

[返回页首] sys::Replace(str,rplto,start,ntimes)：文本替换操作

str： 字符串。被进行替换的初始文本。
rplto：“替换为”字符串，将匹配到的子字符串替换成 rplto 字符串。
start：进行查找替换的开始位置。可以缺省该参数（默认-1），此时根据是否是 sys::reRightToLeft 自动决定开始位置。
ntimes：指定进行替换的次数。可以缺省该参数（默认-1），此时表示替换所有匹配。

返回值：替换后得到的新字符串。

运行错误：1：参数个数非法；2：参数非法；3：内存错误。

[返回页首] sys::IsMatched()：获取是否匹配成功

返回值：返回 true 表示匹配成功，返回 false 表示匹配失败。

例子

[返回页首] sys::GetStart()：获取匹配到的子字符串开始位置

返回值：匹配成功后，获取所匹配到的子字符串的开始位置。如果匹配失败，则返回负值。

例子

[返回页首] sys::GetEnd()：获取匹配到的子字符串结束位置

返回值：匹配成功后，获取所匹配到的子字符串的结束位置。如果匹配失败，则返回负值。

例子

[返回页首] sys::GetGroupStart(nGroupNumber)：获取分组开始位置

nGroupNumber： 整数，分组编号。

返回值： 获取指定分组捕获的字符串的开始位置。如果指定分组未捕获，或者整个表达式未匹配成功，则返回负值。

运行错误：1：非法的参数。

[返回页首] sys::GetGroupEnd(nGroupNumber)：获取分组结束位置

nGroupNumber： 整数，分组编号。

返回值： 获取指定分组捕获的字符串的结束位置。如果指定分组未捕获，或者整个表达式未匹配成功，则返回负值。

运行错误：1：非法的参数。

[返回页首] sys::MaxGroupNumber()：获取正则表达式最大捕获组编号

返回值：返回最大分组编号。

4 字典 [返回页首]

字典（dict）是一个可直接存取的双向链表，可以存放若干任意的Lu数据。字典元素由“键－值”对组成，键只能是字符串，但值可以是任何Lu数据类型。

（1）新建字典

> !!!using("sys");
> new[dict, "aa":1.2, "abc":"luuu"].o[]; //用函数new生成字典，有2组初始化数据。函数o用于输出字典。

用函数dict生成字典更为方便：

> !!!using("sys");
> dict["aa":1.2, "abc":"luuu"].o[]; //用函数dict生成字典，有2组初始化数据。函数o用于输出字典。

（2）得到字典元素

> !!!using("sys");
> main(:a)= a=dict["aa":1.2, "abc":"luu"], o[a."aa", a."abc"];

（3）增加字典元素

> !!!using("sys");
> main(:a)= a=dict["aa":1.2, "abc":"luu"], a."cc"=a."abc"+"88", o[a];

说明：当往字典中增加元素时，若已存在该键，则进行更新。

（4）删除字典

删除指定键－值对：a.dict_del["aa","abc"];

清空字典：a.dict_clear();

删除字典对象，但暂存在缓冲区：del[a];

立即彻底删除字典对象：delete[a];

（5）字典反序

> !!!using("sys");
> main(:a)= a=dict["aa":1.2, "abc":"luu"], o[a], o[a.dict_reverse()];

结果：

> dict{aa : 1.2 , abc : luu}dict{abc : luu , aa : 1.2}

（6）字典存取效率测试 ：在字典a中添加若干元素，元素的键通过变换字符串str的值得到，sum用于求所有元素的值的和。

> !!!using("sys");
> main(:a,i,j,str,t0,sum)= t0=clock(), a=dict[], str="aaaa", sum=0,
> i=0, while{++i<=100, str[1]=i,
> j=1000, while{j<2000, str[2]=j, sum=sum+i+j, a.str=i+j, j++}
> },
> o{"\r\n创建字典耗时", [clock()-t0]/1000., "秒。共", len(a), "个元素。sum=", sum},
> t0=clock(), sum=0,
> i=0, while{++i<=100, str[1]=i,
> j=1000, while{j<2000, str[2]=j, sum=sum+a.str, j++}
> },
> o{"\r\n查询字典耗时", [clock()-t0]/1000., "秒。共", len(a), "个元素。sum=", sum, "\r\n"};

结果：

> 创建字典耗时0.89秒。共100000个元素。sum=155000000
> 查询字典耗时9.4e-002秒。共100000个元素。sum=155000000

5 结构 [返回页首]

结构（struct）是一个线性表，可以存放若干任意的Lu数据。结构成员必须以#开头。结构成员的存储顺序与其定义顺序不一定相同。

（1）新建结构：相当于结构定义

> !!!using("sys");
> new[struct, #num, #姓名 : "luuu", #年龄].o[]; //用函数new生成结构，有3个成员，其中“姓名”成员进行了初始化。函数o用于输出结构。

用函数 struct 生成结构更为方便：

> !!!using("sys");
> struct[#num, #姓名 : "luuu", #年龄].o[]; //用函数new生成结构，有3个成员，其中“姓名”成员进行了初始化。函数o用于输出结构。

（2）复制结构：相当于生成结构对象

> !!!using("sys");
> main(:a)= a=struct[#num, #姓名 : "luuu", #年龄], o[a,"\r\n",copy(a),"\r\n",copy(a, #num:22, #年龄:33),"\r\n"];

结果：

> struct{#num : nil , #姓名 : luuu , #年龄 : nil}
> struct{#num : nil , #姓名 : luuu , #年龄 : nil}
> struct{#num : 22 , #姓名 : luuu , #年龄 : 33}

（3）复制结构：要求有相同的结构成员，依次复制结构成员的值

> !!!using("sys");
> main(:a,b)= a=struct[#num : 55, #姓名 : "luuu", #年龄 : 33], b=struct[#num, #姓名, #年龄], b.=a, o[a,"\r\n",b,"\r\n"];

结果：

> struct{#num : 55 , #姓名 : luuu , #年龄 : 33}
> struct{#num : 55 , #姓名 : luuu , #年龄 : 33}

（4）设置结构：批量对结构成员赋值 ，注意次序是任意的，并且可设置部分成员或全部成员

> !!!using("sys");
> main(:a)= a=struct[#num, #姓名, #年龄], o[a,"\r\n"], a.set(#年龄:33, #num:22).o["\r\n"];

结果：

> struct{#num : nil , #姓名 : nil , #年龄 : nil}
> struct{#num : 22 , #姓名 : nil , #年龄 : 33}

（5）结构成员单独赋值，获取结构成员的值

> !!!using("sys");
> main(:a)= a=struct[#num, #姓名, #年龄], a.#姓名="王强", a.#年龄=33, a.#num=22, o[a,"\r\n",a.#姓名,"\r\n",a.#年龄,"\r\n"];

结果：

> struct{#num : 22 , #姓名 : 王强 , #年龄 : 33}
> 王强
> 33

（6）结构嵌套

> !!!using("sys");
> main(:a)= a=struct[#num, #班级], a.#num=22, a.#班级=struct[#num, #姓名, #年龄],
> a.#班级.#num=88,
> a.#班级.#姓名="王强",
> a.#班级.#年龄=33,
> o[a,"\r\n",a.#num,"\r\n",a.#班级,"\r\n",a.#班级.#num,"\r\n",a.#班级.#姓名,"\r\n",a.#班级.#年龄,"\r\n"];

结果：

> struct{#num : 22 , #班级 : struct[...]}
> 22
> struct{#num : 88 , #姓名 : 王强 , #年龄 : 33}
> 88
> 王强
> 33

（7）效率测试

> !!!using("sys");
> main(:a,i,t0,sum)=
> a=struct{
> #January,
> #February,
> #March,
> #April,
> #May,
> #June,
> #July,
> #August,
> #September,
> #October,
> #November,
> #December
> },
> t0=clock(), sum=0,
> i=0, while{++i<=100000,
> a.#January=1,
> a.#February=2,
> a.#March=3,
> a.#April=4,
> a.#May=5,
> a.#June=6,
> a.#July=7,
> a.#August=8,
> a.#September=9,
> a.#October=10,
> a.#November=11,
> a.#December=12,
> sum=sum+a.#January+a.#February+a.#March+a.#April+a.#May+a.#June+a.#July+a.#August+a.#September+a.#October+a.#November+a.#December
> },
> o{"\r\n耗时", [clock()-t0]/1000., "秒。sum=", sum, "\r\n"};

结果：

> 耗时0.75秒。sum=7800000

使用函数struct_oset和struct_oget存取结构成员会提供运行效率，如下例：

> !!!using("sys");
> main(:a,i,t0,sum)=
> a=struct{
> #January,
> #February,
> #March,
> #April,
> #May,
> #June,
> #July,
> #August,
> #September,
> #October,
> #November,
> #December
> },
> t0=clock(), sum=0,
> i=0, while{++i<=100000,
> a.struct_oset[#January : 1],
> a.struct_oset[#February : 2],
> a.struct_oset[#March : 3],
> a.struct_oset[#April : 4],
> a.struct_oset[#May : 5],
> a.struct_oset[#June : 6],
> a.struct_oset[#July : 7],
> a.struct_oset[#August : 8],
> a.struct_oset[#September : 9],
> a.struct_oset[#October : 10],
> a.struct_oset[#November : 11],
> a.struct_oset[#December : 12],
> sum=sum+a.struct_oget[#January]+a.struct_oget[#February]+a.struct_oget[#March]+a.struct_oget[#April]+a.struct_oget[#May]+a.struct_oget[#June]+a.struct_oget[#July]+a.struct_oget[#August]+a.struct_oget[#September]+a.struct_oget[#October]+a.struct_oget[#November]+a.struct_oget[#December]
> },
> o{"\r\n耗时", [clock()-t0]/1000., "秒。sum=", sum, "\r\n"};

结果：

> 耗时0.562秒。sum=7800000

Matlab2009a代码：

> a=struct('January',1,'Febrary',2,'March',3,'April',4,'May',5,'June',6,'July',7,'August',8,'September',9,'October',10,'November',11,'December',12);
> tic;
> sum=0;
> for i=1:100000
> a.January=1;
> a.February=2;
> a.March=3;
> a.April=4;
> a.May=5;
> a.June=6;
> a.July=7;
> a.August=8;
> a.September=9;
> a.October=10;
> a.November=11;
> a.December=12;
> sum=sum+a.January+a.February+a.March+a.April+a.May+a.June+a.July+a.August+a.September+a.October+a.November+a.December;
> end
> toc,
> sum

结果：

> Elapsed time is 3.275743 seconds.
> sum =
> 7800000

6 类 [返回页首]

类（class）是一个具有数据成员和方法成员的自定义数据结构。类可以继承和派生，类的层次结构是一棵树。

类对象（obj）是类的实例。

（1）类定义

> !!!using("sys");
> new[class, #人, public : #姓名, private : #性别, #年龄].o[]; //用函数new定义类，有1个公有成员，2个私有成员。函数o用于输出类定义。

结果：

>     class{#人 :
>     private:
>       #性别, #年龄,
>     method:

>     public:
>       #姓名,
>     method:
>       #__init__ : 0, #__del__ : 0
>     }

用函数class定义类更为方便：

> !!!using("sys");
> class[#人, public : #姓名, private : #性别, #年龄].o[]; //用函数new定义类，有1个公有成员，2个私有成员。函数o用于输出类定义。

输出结果与上面相同。

（2）单一继承

> !!!using("sys");
> class[#人, public : #姓名, private : #性别, #年龄],
> class[#学生, #人, public : #学校, #班级].o[];

结果：

>     class{#学生 : #人,
>     private:

>     method:

>     public:
>       #学校, #班级,
>     method:
>       #__init__ : 0, #__del__ : 0
>     }

（3）类对象

> !!!using("sys");
> main(:a,b)=
> class[#人, public : #姓名, #性别, #年龄],
> a=class[#学生, #人, public : #学校, #班级],
> b=obj[a],
> b.#学校="实验中学", b.#班级="二年级", b.#姓名="王强", b.#性别="男", b.#年龄=12,
> o[b, b.#学校," ", b.#班级," ", b.#姓名," ", b.#性别, " ", b.#年龄, "\r\n"];

结果：

>     class obj{#学生 : #人,
>     private:
>     public:
>       #学校 : 实验中学,
>       #班级 : 二年级
>     }
>     实验中学  二年级  王强  男  12

说明：如果基类“#人”中#性别和#年龄被定义为私有成员，将无法直接进行存取。

（4）多重继承及构造函数和析构函数

例子1：

> !!!using("sys");
> initA(p)= o["\r\nA的构造函数!"];
> initB(p)= o["\r\nB的构造函数!"];
> initC(p)= o["\r\nC的构造函数!"];
> initD(p)= o["\r\nD的构造函数!"];
> delA(p) = o["\r\nA的析构函数!"];
> delB(p) = o["\r\nB的析构函数!"];
> delC(p) = o["\r\nC的析构函数!"];
> delD(p) = o["\r\nD的析构函数!"];
> main()=
> class[#A, method : #__init__ : @initA, #__del__ : @delA],
> class[#B, #A, method : #__init__ : @initB, #__del__ : @delB],
> class[#C, #A, method : #__init__ : @initC, #__del__ : @delC],
> class[#D, #B, #C, method : #__init__ : @initD, #__del__ : @delD].obj[].delete[];

结果：

> A的构造函数!
> B的构造函数!
> A的构造函数!
> C的构造函数!
> D的构造函数!
> D的析构函数!
> B的析构函数!
> A的析构函数!
> C的析构函数!
> A的析构函数!

例子2：

> !!!using("sys");
> initA(p)= p.#a=0;
> initB(p)= p.#a=1;
> initC(p)= p.#a=2;
> initD(p)= p.#a=3;
> main(:c)=
> class[#A, public: #a, method : #__init__ : @initA],
> class[#B, #A, public: #a, method : #__init__ : @initB],
> class[#C, #A, public: #a, method : #__init__ : @initC],
> c=class[#D, #B, #C, public: #a, method : #__init__ : @initD].obj[],
> o[c.#a," ",c.#B.#a," ",c.#C.#a," ",c.#B.#A.#a," ",c.#C.#A.#a,"\r\n"],
> c.#B.#A.#a=5, c.#C.#A.#a=6, o[c.#B.#A.#a," ",c.#C.#A.#a,"\r\n"];

结果：

> 3 1 2 0 0
> 5 6

例子3：

> !!!using("sys");
> initA(p)= p.#a=0;
> initB(p)= p.#b=1;
> initC(p)= p.#c=2;
> initD(p)= p.#d=3;
> main(:c)=
> class[#A, public: #a, method : #__init__ : @initA],
> class[#B, #A, public: #b, method : #__init__ : @initB],
> class[#C, #A, public: #c, method : #__init__ : @initC],
> c=class[#D, #B, #C, public: #d, method : #__init__ : @initD].obj[],
> o[c.#a," ",c.#b," ",c.#c," ",c.#d,"\r\n"],
> c.#a=5, c.#b=6, c.#c=7, c.#d=8,
> o[c.#a," ",c.#b," ",c.#c," ",c.#d,"\r\n"],
> c.#B.#A.#a=11, c.#C.#A.#a=12, o[c.#a," ",c.#B.#A.#a," ",c.#C.#A.#a,"\r\n"];

结果：

> 0 1 2 3
> 5 6 7 8
> 11 11 12

（5）成员函数：第一个参数为对象指针

例子1：

> !!!using("sys");
> setA(p,x)= p.#a=x;
> setB(p,x)= p.#a=x;
> setC(p,x)= p.#a=x;
> getA(p)= p.#a;
> getB(p)= p.#a;
> getC(p)= p.#a;
> main(:c)=
> class[#A, public: #a, method : #mGetA : @getA, #mSetA : @setA],
> class[#B, public: #a, method : #mGetB : @getB, #mSetB : @setB],
> c=class[#C, #A, #B, public: #a, method : #mGetC : @getC, #mSetC : @setC].obj[],
> c.#mSetA=5, c.#mSetB=6, c.#mSetC=7,
> o[c.#mGetA," ",c.#mGetB," ",c.#mGetC,"\r\n"];

结果：

> 5 6 7

说明：类的方法成员和数据成员用法几乎相同，但方法可以接受多个参数，如下例。

例子2：

> !!!using("sys");
> out(p,x,y,z)= o[x,y,z,"\r\n"];
> main(:c)=
> c=class[#A, method : #mOut : @out].obj[],
> c.#mOut := [5,6,7],
> c.#mOut."***".(888)."***";

结果：

> 567
> ***888***

（6）类对象复制

> !!!using("sys");
> setA(p,x,y)= p.#a=x, p.#b=y;
> sumA(p)= p.#a+p.#b;
> copyAB(s,t)= s.#a=t.#a, s.#b=t.#b;
> class[#A, public : #a, public : #b, method : #__copy__ : @copyA B, #setA : @setA, #sumA : @sumA],
> class[#B, #A, public : #a, public : #b, method : #__copy__ : @copyAB];
> main(:a,b)=
> a=obj[class_handle(#B)], b=obj[class_handle(#B)],
> a.#a=1, a.#b=2, a.#setA:=[8,9],
> b.=a,
> b.#a+b.#b+b.#sumA;

结果：

> 20

（7）多态性

> !!!using("sys");
> getA()= 1;
> getB()= 2;
> getC()= 3;
> class[#A, method : #mGet : @getA],
> class[#B, #A, method : #mGet : @getB],
> class[#C, #B, method : #mGet : @getC];
> main(:a,b,c)=
> c=obj[class_handle(#C)],
> o[c.#mGet," ",c.#B.#mGet," ",c.#B.#A.#mGet,"\r\n"],
> b=c.#B, a=b.#A, //获得基类对象
> o[c.#mGet," ",b.#mGet," ",a.#mGet,"\r\n"];

结果：

> 3 2 1
> 3 2 1

（8）效率测试

> !!!using("sys");
> main(:a,i,t0,sum)=
> a=class{#A,
> public:
> #January,
> #February,
> #March,
> #April,
> #May,
> #June,
> #July,
> #August,
> #September,
> #October,
> #November,
> #December
> }.obj[],
> t0=clock(), sum=0,
> i=0, while{++i<=100000,
> a.#January=1,
> a.#February=2,
> a.#March=3,
> a.#April=4,
> a.#May=5,
> a.#June=6,
> a.#July=7,
> a.#August=8,
> a.#September=9,
> a.#October=10,
> a.#November=11,
> a.#December=12,
> sum=sum+a.#January+a.#February+a.#March+a.#April+a.#May+a.#June+a.#July+a.#August+a.#September+a.#October+a.#November+a.#December
> },
> o{"\r\n耗时", [clock()-t0]/1000., "秒。sum=", sum, "\r\n"};

结果：

> 耗时0.860秒。sum=7800000

比较：前面使用struct的耗时0.75秒，故class比struct稍慢。

使用函数obj_oset和obj_oget存取类成员会提供运行效率，如下例：

> !!!using("sys");
> main(:a,i,t0,sum)=
> a=class{#A,
> public:
> #January,
> #February,
> #March,
> #April,
> #May,
> #June,
> #July,
> #August,
> #September,
> #October,
> #November,
> #December
> }.obj[],
> t0=clock(), sum=0,
> i=0, while{++i<=100000,
> a.obj_oset[#January : 1],
> a.obj_oset[#February : 2],
> a.obj_oset[#March : 3],
> a.obj_oset[#April : 4],
> a.obj_oset[#May : 5],
> a.obj_oset[#June : 6],
> a.obj_oset[#July : 7],
> a.obj_oset[#August : 8],
> a.obj_oset[#September : 9],
> a.obj_oset[#October : 10],
> a.obj_oset[#November : 11],
> a.obj_oset[#December : 12],
> sum=sum+a.obj_oget[#January]+a.obj_oget[#February]+a.obj_oget[#March]+a.obj_oget[#April]+a.obj_oget[#May]+a.obj_oget[#June]+a.obj_oget[#July]+a.obj_oget[#August]+a.obj_oget[#September]+a.obj_oget[#October]+a.obj_oget[#November]+a.obj_oget[#December]
> },
> o{"\r\n耗时", [clock()-t0]/1000., "秒。sum=", sum, "\r\n"};

结果：

> 耗时0.625秒。sum=7800000

[返回页首] sys::class{... ...}：创建类定义

类定义格式如下：

> class{#cMyClass: #cBase1, #cBase2, ... //定义类cMyClass，继承自cBase1和cBase2, ...
> private: //私有数据成员
> #pvMem1, #pvMem2, ...
> method: //私有方法（私有函数成员）
> #vmFun1 ：@Fun1, #vmFun2 ：@Fun2, ...
> public: //公有数据成员
> #plMem1, #plMem2, ...
> method: //公有方法（公有函数成员）
> #__init__ : @init, #__del__ : @delme, #lmFun1 ：@fun1, #lmFun2 ：@fun2, ...
> };

类定义中，类名称、基类名称、成员及方法都是以#开头的标识符，不可重复。类名称在最前面，其次是基类名称；private 和 public 的次序是任意的，且可多次定义； 在 private 后定义的 method 为私有方法，在 public 后定义的 method 为公有方法，若 method 前面没有 private 和 public，默认是公有方法；方法标识符后必须提供函数句柄。类成员的存储顺序与其定义顺序不一定相同。

#__init__和#__del__只可被定义为 公有方法，其中#__init__用于定义构造函数，#__del__用于定义析构函数。若这两个方法被缺省，其函数句柄被自动指定为0。构造函数和析构函数只有一个参数，即对象本身。

若方法有不止一个参数，则方法被调用时，第一个参数总是传入对象本身，相当于C++的this指针。

运行错误：1：非法的类名；2：__init__和__del__只能是公有方法；3：类名或基类名有重名；4：不可识别关键字；5：缺少函数句柄；6：不可识别关键字或成员；7：基类没有定义或循环定义。

约定：类名称以字母c开头；私有数据成员以pv开头；公有数据成员以pl开头 ；私有方法成员以vm开头；公有方法成员以lm开头。

[返回页首] sys::obj{pClass}：创建类对象

pClass是类定义的句柄。

创建类对象时，将自动调用每一个基类的构造函数#__init__初始化基类对象。对象被销毁时，将自动调用每一个基类的析构函数#__del__销毁基类对象。

语句 a.=b 将对象b的内容复制到对象a，要求a和b具有相同的类定义，若类定义中定义了方法#__copy__（有且只有2个参数），将自动调用该方法进行对象复制，否则仅依次复制类成员的值。

运行错误：1：不可识别类定义。

[返回页首] sys::obj_method(#FunName : pObj,... ...)：调用类对象的方法。

#FunName：以#开头的标识符指出函数名。
pObj：类对象。

运行错误：1：参数太少；2：不可识别的函数标识或对象；3：不可识别类对象；4：参数不匹配；5：找不到指定的方法。

7 文件系统函数

在操作文件时，先用函数fopen打开文件，然后对文件进行读写，最后用函数fclose关闭文件（或者用函数delete销毁 文件：delete(hFile)）。如果文件没有关闭，在释放lusystem时，会自动关闭打开的文件。

[返回页首] sys::fopen("filename","mode")：打开文件

"filename"：文件名，可以包含路径和文件名两部分。
"mode"：打开文件的类型。关于文件类型的规定参见下面说明。
返回值：操作成功，返回有效的文件句柄hFile。否则返回nil。无需检查文件句柄是否有效，相应的文件操作函数会自动进行检查。

运行错误：1：需要字符串参数指出文件名和文件访问模式；2：文件访问模式错误。

说明：

>     文件名格式：

>     	"B:TEST.DAT"
>     	"C:\\TC\\TEST.DAT"

>     注意：如果将路径写成"C:\TC\TEST.DAT"是不正确的, 这一点要特别注意。

>     fopen函数用来打开一个文件，其调用的一般形式为：fopen(文件名,使用文件方式)
>      其中，“文件名”是被打开文件的文件名。“使用文件方式”是指文件的类型和操作要求。“文件名”是一个字符串。例如：
>     	fopen("file a","r");
>     其意义是在当前目录下打开文件file a，只允许进行“读”操作。
>     又如：
>     	fopen("c:\\hzk16","rb")
>     其意义是打开C驱动器磁盘的根目录下的文件hzk16， 这是一个二进制文件，只允许按二进制方式进行读操作。
>     两个反斜线“\\ ”中的第一个表示转义字符，第二个表示根目录。使用文件的方式共有12种，下面给出了它们的符号和意义。

>                        表 文件操作类型

>     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

>           字符                 含义

>     ────────────────────────────

>            "r"            打开文字文件只读

>            "w"            创建文字文件只写

>            "a"            增补, 如果文件不存在则创建一个

>            "r+"           打开一个文字文件读/写

>            "w+"           创建一个文字文件读/写

>            "a+"           打开或创建一个文件增补

>            "b"            二进制文件(可以和上面每一项合用)

>            "t"            文这文件(默认项)

>     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

>     文件使用方式 　　　　　　　意 义

>     "rt"　　　　　　只读打开一个文本文件，只允许读数据
>     "wt"　　　　　　只写打开或建立一个文本文件，只允许写数据
>     "at"　　　　　　追加打开一个文本文件，并在文件末尾写数据
>     "rb"　　　　　　只读打开一个二进制文件，只允许读数据
>     "wb"　　　　 　 只写打开或建立一个二进制文件，只允许写数据
>     "ab" 　　　　 　追加打开一个二进制文件，并在文件末尾写数据
>     "rt+"　　　　　 读写打开一个文本文件，允许读和写
>     "wt+"　　　　　 读写打开或建立一个文本文件，允许读写
>     "at+"　　　　　 读写打开一个文本文件，允许读，或在文件末追加数据
>     "rb+"　　　　　 读写打开一个二进制文件，允许读和写
>     "wb+"　　　　　 读写打开或建立一个二进制文件，允许读和写
>     "ab+" 　　　　　读写打开一个二进制文件，允许读，或在文件末追加数据

>     对于文件使用方式有以下几点说明：

>     1. 文件使用方式由r,w,a,t,b，+六个字符拼成，各字符的含义是：

>     	r(read): 读
>     	w(write): 写
>     	a(append): 追加
>     	t(text): 文本文件，可省略不写
>     	b(banary): 二进制文件
>     	+: 读和写

>     2. 凡用"r"打开一个文件时，该文件必须已经存在，且只能从该文件读出。

>     3. 用"w"打开的文件只能向该文件写入。若打开的文件不存在，则以指定的文件名建立该文件，若打开的文件已经存在，则将该文件删去，重建一个新文件。

>     4. 若要向一个已存在的文件追加新的信息，只能用"a "方式打开文件。但此时该文件必须是存在的，否则将会出错。

>     5. 在打开一个文件时，如果出错，fopen将返回一个空指针值NULL给文件句柄hFile，后续文件操作将不能正常进行。

>     6. 把一个文本文件读入内存时，要将ASCII码转换成二进制码，而把文件以文本方式写入磁盘时，也要把二进制码转换成ASCII码，因此文本文件的读写要花费较多的转换时间。

>     7. 对二进制文件的读写不存在转换。

>     8. Unicode文本文件的标志是：文件长度是偶数，首字符为sys::UTEXT（该字符仅是一个标志，不包括在有效的Unicode文本文件内容中）。

>     如果要打开一个CCDOS子目录中, 文件名为CLIB的二进制文件, 可写成:

>     	fopen("c:\\ccdos\\clib", "rb");

[例子1] 读Unicode文本文件（以起始字符 UTEXT 为标志）并显示其内容，表达式之间用模块变量传递参数

> !!!using["sys"]; //使用命名空间“sys”
> main(:f,len,s,x)=
> f=fopen["aa.txt","rb"], //打开文件，"aa.txt"必须是已经存在的Unicode文本文件
> fseek(f,0,SEEK_END), //把文件指针移动到文件末尾，记得显示文件内容时要把指针移动回到文件头部
> len=ftell[f], //获取文件指针的位置，相当于得到文件的长度了
> s=new[string,len+1], //根据文件长度申请内存空间，使读取文件长度获得一定的灵活性，注意后面加一的意义
> rewind[f], //把文件指针移动到文件开头，当然也可以用fseek()完成这个动作
> x=0, fread[f,&x,2], //读取第一个字符到x，若为Unicode文本文件，该字符应为UTEXT，可以进行判断，这里省略了
> fread[f,s], //读取文件
> fclose[f], //关闭文件
> printf["%s\r\n",s]; //输出文件内容

[例子2] 二进制文件读写

> !!!using["sys"];
> main(:f,d,e)=
> d=new[ints,5,data:1,2,3,4,5], e=new[ints,5,data:0,0,0,0,0],
> f=fopen["bb.txt","wb+"],
> fwrite[f,d], rewind[f], fread[f,e],
> fclose[f],
> printf{"%i %i %i %i %i\r\n",e[0],e[1],e[2],e[3],e[4]};

[例子3] Unicode文本文件读写，用二进制文件实现

> !!!using["sys"];
> main(:f,d,e,x)=
> d=new[string,"hello!\r\nLu!"],e=new[string,80],
> f=fopen["cc.txt","wb+"],
> fwrite[f,UTEXT,2], fwrite[f,d],
> rewind[f], x=0, fread[f,x,2], fread[f,e],
> fclose[f],
> printf["%s\r\n",e];

[返回页首] sys::fclose(hFile)：关闭文件
hFile：文件句柄。
返回值：操作成功，返回0。否则返回sys::EOF。
说明：也可以用delete(hFile)关闭文件。如果使用del(hFile)，将不能立即关闭文件。

[返回页首] sys::fwrite(hFile,value,size)或sys::fwrite(hFile,buffer,count)：写文件

hFile：文件句柄。
value：简单数据（支持整数、实数、复数和向量）。
size：简单数据的字节数。size=1～24。size=1表示8位数（如一个ASCII字符）；size=2表示16位数（如一个Unicode字符）；size=4表示32位数；size=8表示64位数（Lu默认整数或实数）。 可以缺省该参数，此时，若value是一个整数、实数、指针，size=8；若value是一个复数，size=16；若value是一个向量，size=24。
buffer：数组数据（支持ASCII字符串 、Unicode字符串、整数数组、实数数组）。将写数组的全部数据，或者count指定的数据数目。
count：写入数据的最大数目。如果该值大于数组长度，该值被忽略，将写全部数据。该参数可以缺省，表示写全部数据。
返回值：返回写入的数据对象的数目。

运行错误：1：只能有2个或3个参数；2：不可识别参数，例如非法的文件句柄等；3：数据的字节数或数据数目非法；4：不可识别的字符串；5：不可识别的ASCII字符串；6：不可识别的数组；7：简单数据的字节数太多。

[返回页首] sys::fread(hFile,value,size)或sys::fread(hFile,buffer,count)：读文件

hFile：文件句柄。
value：简单数据（支持整数、实数、复数和向量）。
size：简单数据 的字节数。size=1～24。size=1表示8位数（如一个ASCII字符）；size=2表示16位数（如一个Unicode字符）；size=4表示32位数；size=8表示64位数（Lu默认整数或实数）。可以缺省该参数，此时，若value是一个整数、实数、指针，size=8；若value是一个复数，size=16；若value是一个向量，size=24。
buffer：数组数据（支持ASCII字符串 、Unicode字符串、整数数组、实数数组）。将读满数组的全部数据，或者count指定的数据数目。
count：读入数据的最大数目。如果该值大于数组长度，该值被忽略，仅读满全部数据。该参数可以缺省，表示读全部数据。
返回值：返回读取的数据对象的数目。

运行错误：1：只能有2个或3个参数；2：不可识别参数，例如非法的文件句柄等；3：数据的字节数或数据数目非法；4：不可识别的字符串；5：不可识别的ASCII字符串；6：不可识别的数组；7：简单数据的字节数太多。

[返回页首] sys::fseek(hFile,offset,origin)： 设置文件指针的位置

hFile：文件句柄。
offset：文件指针从origin开始的偏移字节数。
origin：起始位置，函数从该位置开始增加偏移量。只能取sys::SEEK_CUR（当前位置），sys::SEEK_END（文件尾）和sys::SEEK_SET（文件头）。
返回值：成功时返回0，否则返回非0值。

运行错误：1：不可识别参数；2：非法的起始位置；3：非法的文件句柄。

[返回页首] sys::feof(hFile)： 判断是否到文件尾

hFile：文件句柄。
返回值：没有到达文件尾时返回0，否则返回非0值。

运行错误：1：非法的文件句柄。

[返回页首] sys::fflush(hFile)：刷新一个打开的流 ，将缓冲区中的内容写入文件

hFile：文件句柄。
返回值：操作成功，返回0。否则返回sys::EOF。

运行错误：1：非法的文件句柄。

[返回页首] sys::ftell(hFile)：获取文件指针位置

hFile：文件句柄。
返回值：操作失败返回-1。

运行错误：1：非法的文件句柄。

[返回页首] sys::rewind(hFile)：把文件指针设置回文件的起始位置

hFile：文件句柄。
返回值：hFile。

运行错误：1：非法的文件句柄。

8 格式化输入输出函数

[返回页首] sys::printf(FormatStr,x1,x2,... ...)：格式化输出到标准设备

FormatStr：格式串（字符串），可包括文本和下表中的控制码。格式化字符串包括两部分内容：一部分是正常字符，这些字符将按原样输出；另一部分是格式化规定字符，以“%”开始, 后跟一个或几个规定字符用来确定输出内容格式。
x1,x2,... ...：与格式串中的控制代码相匹配的数据项列表。数据项的个数与格式说明的个数一致，格式说明和数据项在顺序上相互对应。
返回值：输出字符数（出错时返回-1）。

运行错误：1：不能将字符串发送到自己的地址；2：字符串太多，无法申请缓冲区；3：内存错误；4：缺少格式字符串；5：缺少数据项；6：非法的字符串指针；7：无法识别格式串；8：数据项多于格式符；9：格式化输出错误。

函数printf()的格式说明符

说明符 | 描述
%% | 说明一个宽字符“%”。
%C | 说明一个宽字符。
%d | 说明一个带符号的10进制整数。
%e | 说明一个带符号的双精度浮点值，该值是用带小写字母“e”的科学计数法表示的。
%E | 说明一个带符号的双精度浮点值，该值是用带大写字母“E”的科学计数法表示的。
%f | 说明一个带符号的双精度浮点值。
%g | 说明一个带符号的双精度浮点值，该值是用正常方法表示的，或者是用带小写字母“e”的科学计数法表示的。
%G | 说明一个带符号的双精度浮点值，该值是用正常方法表示的，或者是用带大写字母“E”的科学计数法表示的。
%i | 说明一个带符号的10进制整数。
%n | 说明一个数，该数用于接收已写字符的个数。
%o | 说明一个无符号的8进制整数（此格式符工作不正常） 。
%p | 说明一个指针，在32位平台上，指针为一个数的前4个字节。
%s | 说明一个字符串，如果指定域宽，域宽最大为99。
%u | 说明一个无符号的10进制整数。
%x | 说明一个无符号的16进制整数，整数中的字母是用小写字母表示的。
%X | 说明一个无符号的16进制整数，整数中的字母是用大写字母表示的。

printf格式控制符的完整格式：

printf的格式控制的完整格式：
% - 0 m.n l、h或I64 格式字符
下面对组成格式说明的各项加以说明：
①%：表示格式说明的起始符号，不可缺少。
②-：有-表示左对齐输出，如省略表示右对齐输出。
③0：有0表示指定空位填0,如省略表示指定空位不填。
④m.n：m指域宽，即对应的输出项在输出设备上所占的字符数。n指精度。用于说明输出的实型数的小数位数。为指定n时，隐含的精度为n=6位。
⑤l、h或I64：l对整型指long型，对实型指double型。h用于将整型的格式字符修正为short型。I64用于说明一个64位整数。
－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
格式字符
格式字符用以指定输出项的数据类型和输出格式。
①d格式：用来输出十进制整数。有以下几种用法：
%d：按整型数据的实际长度输出。
%md：m为指定的输出字段的宽度。如果数据的位数小于m，则左端补以空格，若大于m，则按实际位数输出。
%ld：输出长整型数据。
②o格式：以无符号八进制形式输出整数。对长整型可以用"%lo"格式输出。同样也可以指定字段宽度用“%mo”格式输出。
例：
printf("%d, %o", -1, -1);
运行结果：-1,177777
程序解析：-1在内存单元中（以补码形式存放）为(1111111111111111)2，转换为八进制数为(177777)8。
③x格式：以无符号十六进制形式输出整数。对长整型可以用"%lx"格式输出。同样也可以指定字段宽度用"%mx"格式输出。
④u格式：以无符号十进制形式输出整数。对长整型可以用"%lu"格式输出。同样也可以指定字段宽度用“%mu”格式输出。
⑤c格式：输出一个字符。
⑥s格式：用来输出一个串。有几中用法
%s：例如:printf("%s", "CHINA")输出"CHINA"字符串（不包括双引号）。
%ms：输出的字符串占m列，如字符串本身长度大于m，则突破获m的限制,将字符串全部输出。若串长小于m，则左补空格。
%-ms：如果串长小于m，则在m列范围内，字符串向左靠，右补空格。
%m.ns：输出占m列，但只取字符串中左端n个字符。这n个字符输出在m列的右侧，左补空格。
%-m.ns：其中m、n含义同上，n个字符输出在m列范围的左侧，右补空格。如果n>m，则自动取n值，即保证n个字符正常输出。
⑦f格式：用来输出实数（包括单、双精度），以小数形式输出。有以下几种用法：
%f：不指定宽度，整数部分全部输出并输出6位小数。
%m.nf：输出共占m列，其中有n位小数，如数值宽度小于m左端补空格。
%-m.nf：输出共占n列，其中有n位小数，如数值宽度小于m右端补空格。
⑧e格式：以指数形式输出实数。可用以下形式：
%e：数字部分（又称尾数）输出6位小数，指数部分占5位或4位。
%m.ne和%-m.ne：m、n和”-”字符含义与前相同。此处n指数据的数字部分的小数位数，m表示整个输出数据所占的宽度。
⑨g格式：自动选f格式或e格式中较短的一种输出，且不输出无意义的零。
－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
对于单精度数，使用%f格式符输出时，仅前7位是有效数字，小数6位。
对于双精度数，使用%lf格式符输出时，前16位是有效数字，小数6位。

例子：

> sys::printf("a=%d\r\n", 123); //输出十进制整数a=123
> sys::printf("a=%6d\r\n", 123); //输出6位十进制数a= 123
> sys::printf("a=%06d\r\n", 123); //输出6位十进制数a=000123
> sys::printf("a=%2d\r\n", 123); //超过2位,按实际值输出a=123
> sys::printf("i=%-6d\r\n", 123); //输出左对齐6位十进制整数i=123
> sys::printf("i=%p\r\n", 1111111111111); //输出地址类似于i=211C7000
> sys::printf("f=%f\r\n", 3.141593); //输出浮点数f=3.141593
> sys::printf("f=%6.4f\r\n", 3.141593); //输出6位其中小数点后4位的浮点数f=3.1416
> sys::printf("x=%lf\r\n", 0.123457); //输出长浮点数x=0.123457
> sys::printf("x=%18.16lf\r\n", 0.1234567898765432);//输出18位其中小数点后16位的长浮点x=0.1234567898765432
> sys::printf("c=%C\r\n", 66); //输出字符c=B
> sys::printf("s=%s\r\n", "hello！您好！"); //输出数组字符串s=hello！您好！
> sys::printf("X=%X\r\n", 1234567890123456789); //输出16进制整数X=7DE98115
> sys::printf("X=%I64X\r\n", 1234567890123456789); //输出16进制整数X=112210F47DE98115

[返回页首] sys::sprintf(str,FormatStr,x1,x2,... ...)：格式化输出到字符串

str：动态字符串。所有输出将保存到该字符串。 如果该字符串不够用，该函数会自动增加字符串的大小。
FormatStr：格式字符串，可包括文本和控制码。格式化字符串包括两部分内容：一部分是正常字符，这些字符将按原样输出；另一部分是格式化规定字符，以“%”开始, 后跟一个或几个规定字符用来确定输出内容格式。
x1,x2,... ...：与格式串中的控制代码相匹配的数据项列表。数据项的个数与格式说明的个数一致，格式说明和数据项在顺序上相互对应。
返回值：输出字符数（出错时返回-1）。

运行错误：1：非法的动态字符串指针str；2：不能将字符串发送到自己的地址；3：字符串太多，无法申请缓冲区；4：内存错误；5：缺少格式字符串；6：缺少数据项；7：非法的字符串指针；8：无法识别格式串；9：数据项多于格式符；10：格式化输出错误。

说明：该函数功能与 printf 类似，仅将输出定向到字符串，请参考 printf 的说明。

例子：

> (:s)= s=new[string,100,""],sys::sprintf(s,"a=%06d\r\n", 123),sys::printf["%s",s]; //输出6位十进制数a=000123

[返回页首] sys::fprintf(pfile,FormatStr,x1,x2,... ...)：格式化输出到文件

pfile：文件句柄。所有输出将保存到该文件。
FormatStr：格式字符串，可包括文本和控制码。格式化字符串包括两部分内容：一部分是正常字符，这些字符将按原样输出；另一部分是格式化规定字符，以“%”开始, 后跟一个或几个规定字符用来确定输出内容格式。
x1,x2,... ...：与格式串中的控制代码相匹配的数据项列表。数据项的个数与格式说明的个数一致，格式说明和数据项在顺序上相互对应。
返回值：输出字符数（出错时返回-1）。

运行错误：1：非法的文件句柄；2：缺少格式字符串；3：缺少数据项；4：非法的字符串指针；5：无法识别格式串；6：数据项多于格式符；7：格式化输出错误。

说明：该函数功能与 printf 类似，仅将输出定向到文件，请参考 printf 的说明。

例子：

> !!!using["sys"];
> main(:f,d,e,x)=
> d=new[string,"您好！\r\nhello!\r\n"],
> f=fopen["dd.txt","wb+"],
> fwrite[f,UTEXT,2], fprintf(f,"a=%06d\r\n%s", 123,d),
> e=new[string,(ftell(f)-1)/2],
> rewind[f], x=0, fread[f,x,2], fread[f,e],
> fclose[f],
> printf["\r\n%s\r\n",e];

[返回页首] sys::sscanf(str,FormatStr,&x1,&x2,... ...)：从字符串格式化输入

str：字符串指针。所有数据将从该字符串读取。
FormatStr：格式串（字符串），可包括文本和控制码。格式化字符串包括两部分内容：一部分是正常字符 ，另一部分是格式化规定字符，以“%”开始, 后跟一个或几个规定字符用来确定输出内容格式。
&x1,&x2,... ...：与格式串中的控制代码相匹配的数据项列表。数据项的个数与格式说明的个数一致，格式说明和数据项在顺序上相互对应。
返回值：返回成功地处理的数据项的个数（出错时返回-1）。在此例中，若仅读取了x1，返回3；若处理到x2，返回4；以此类推。

运行错误：1：源字符串不存在；2：缺少格式串；3：源字符串的偏移量非法；4：内存错误；5：缺少数据项；6：非法的字符串指针；7：源字符串与目的字符串相同，无法操作；8： 静态字符串缓冲区太小，无法接收字符；9：无法识别格式串；10：数据项多于格式符 。

函数sscanf()的格式说明符

说明符 | 描述
%& | 说明一个相对于源字符串的偏移量，将从该位置从字符串中读取数据。该说明符仅用于格式串的开头。该说明符仅用于sscanf()函数。
%% | 说明一个宽字符“%”。
%C | 说明一个宽字符。
%d | 说明一个带符号的10进制整数。
%e | 说明一个带符号的双精度浮点值，该值是用带小写字母“e”的科学计数法表示的。
%E | 说明一个带符号的双精度浮点值，该值是用带大写字母“E”的科学计数法表示的。
%f | 说明一个带符号的双精度浮点值。
%g | 说明一个带符号的双精度浮点值，该值是用正常方法表示的，或者是用带小写字母“e”的科学计数法表示的。
%G | 说明一个带符号的双精度浮点值，该值是用正常方法表示的，或者是用带大写字母“E”的科学计数法表示的。
%i | 说明一个带符号的10进制整数。
%n | 说明一个数，该数用于接收已读字符的个数。在函数fscanf()中，该数用于接收当前的文件指针位置。
%o | 说明一个无符号的8进制整数（此格式符工作不正常） 。
%p | 说明一个指针，在32位平台上，指针为一个数的前4个字节。
%s | 说明一个字符串。
%u | 说明一个无符号的10进制整数。
%x | 说明一个无符号的16进制整数，整数中的字母是用小写字母表示的。
%X | 说明一个无符号的16进制整数，整数中的字母是用大写字母表示的。

sscanf 格式控制符的完整格式：{%[*] [width] [{h | l | I64 | L}]type | 非%符号}

说明：

1、* 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入(也就是不把此数据读入参数中) 。
2、{a|b|c}表示a,b,c中选一，[d],表示可以有d也可以没有d。
3、width表示读取宽度。
4、{h | l | I64 | L}:参数的size,通常h表示单字节size，I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
5、type :这就很多了，就是%s,%d之类。
6、特别地：%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉，不会向目标参数中写入值

支持集合操作：

%[a-z] 表示匹配a到z中任意字符，贪婪性(尽可能多的匹配)
%[aB'] 匹配a、B、'中一员，贪婪性
%[^a] 匹配非a的任意字符，贪婪性

%<a-z> 表示匹配a到z中任意字符，贪婪性(尽可能多的匹配)
%<aB'> 匹配a、B、'中一员，贪婪性
%<^a> 匹配非a的任意字符，贪婪性

例子1：读一个字符串

> !!!using["sys"];
> main(:s,buf)=
> s=new[string,"您好！\r\nhello!\r\n"], buf=new[string,80],
> sscanf(s, "%s", buf), //读第1个字符串
> printf["\r\n%s\r\n\r\n",buf],
> sscanf(s, "%*s%s",buf), //读第2个字符串
> printf["\r\n%s\r\n\r\n",buf],
> sscanf(s, "%&%s",1,buf), //从第2个字符开始读
> printf["\r\n%s\r\n\r\n",buf];

[返回页首] sys::fscanf(pfile,FormatStr,&x1,&x2,... ...)：从文件格式化输入

pfile：文件句柄。将从该文件中读取格式化数据。
FormatStr：格式串字符串，可包括文本和控制码。格式化字符串包括两部分内容：一部分是正常字符 ，另一部分是格式化规定字符，以“%”开始, 后跟一个或几个规定字符用来确定输出内容格式。
&x1,&x2,... ...：与格式串中的控制代码相匹配的数据项列表。数据项的个数与格式说明的个数一致，格式说明和数据项在顺序上相互对应。
返回值：返回成功地处理的数据项的个数（出错时返回-1）。在此例中，若仅读取了x1，返回3；若处理到x2，返回4；以此类推。

运行错误：1：非法的文件句柄；2：缺少格式串；3：缺少数据项；4：非法的字符串指针；5：内存错误；6： 静态字符串缓冲区太小，无法接收字符；7：无法识别格式串；8：数据项多于格式符 。

说明：该函数功能与 sscanf 类似，但从文件中读取数据，请参考 sscanf 的说明。

例子1：读一个字符串

> !!!using["sys"];
> main(:f,s,buf)=
> buf=new[string,80], f=fopen["aa.txt","rb"], //Unicode文件“aa.txt”要预先存在
> fread[f,0,2], fscanf(f, "%s", buf), //读第1个字符串
> printf["\r\n%s\r\n\r\n",buf],
> rewind[f], fread[f,0,2], fscanf(f, "%*s%s",buf), //读第2个字符串
> printf["\r\n%s\r\n\r\n",buf],
> fseek[f,6,SEEK_SET], fscanf(f, "%s",buf), //从第3个字符开始读
> printf["\r\n%s\r\n\r\n",buf];

[返回页首] sys::setlocale(category,locale,str)：设置当前地域的各种要素

category：要被修改的地域要素。只能取LC_ALL（设置所有类别）、LC_COLLATE（设置与函数strcoll()等相关联的地域类别）、LC_CTYPE（设置与宽字符关联的地域类别）、LC_MONETARY（设置影响内存格式的地域类别）、LC_NUMERIC（设置影响小数点的地域类别）和LC_TIME（设置影响时间函数的地域类别）。
locale：地域名字符串。
str：字符串地址，用于接收原先的地域字符串。
返回值：返回str。如果字符串缓冲区太小，仅接收部分地域字符串，且返回-1。

运行错误：1：参数非法。

10 其他 [返回页首]

[返回页首] sys::lufun(hFor:x1,x2,...,xn : xx)：以Lu表的元素为自变量进行函数调用。

hFor为函数句柄；x1,x2,...,xn : xx为等长的Lu表；xx用于存放结果，可缺省。若缺省xx，返回一个Lu表存放结果，否则该函数返回xx。该函数以x1,x2,...,xn的第i个元素为自变量，用函数hFor进行计算，结果存入xx的第i个单元。

运行错误：1：至少需要2个参数；2：指定的表达式不存在；3：Lu表个数与自变量个数不相等；4：不是Lu表；5：Lu表长度不匹配；6：内存错误。

例子：

> !!!using("sys");
> f(x,y)=x+y;
> lufun[@f,luu(1.,"aa",5),luu(2.,"bb",5)].o[];

[返回页首] sys::ShellExecute(hwnd,"lpOperation","lpFile","lpParameters","lpDirectory",nShowCmd)：执行外部程序
hwnd：窗口句柄（该句柄是一个指针或者nil，一般为nil）；
lpOperation：指定本命令所要执行的动作；
lpFile：指定本命令所要操作的文件；
lpParameters：指定操作文件时所使用的参数；
lpDirectory：指定本命令所使用的缺省路径；
nShowCmd：显示方式。
运行成功返回一个整数标识的代码，否则返回nil。
例子：
打开一个应用程序： sys::ShellExecute(nil,"open","calc.exe","","",0);
打开一个网页： sys::ShellExecute(nil,"open","http://www.forcal.net","","",0);
用系统打印机打印文档：sys::ShellExecute(nil,"print","openlu.ini","","",0);
查找文件： sys::ShellExecute(nil,"find","","","",0);

版权所有© Lu程序设计 2011-2014，保留所有权利
E-mail: forcal@sina.com QQ：630715621
最近更新: 2014年01月19日