欢迎访问 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]的语句时将调用该函数。
in 该函数是重载函数,用于迭代获取若干luu元素的值。 与Lu核心库中lu对象的in函数用法完全相同。
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]的语句时将调用该函数。
in 该函数是重载函数,用于迭代获取若干String字符串元素的值。 与Lu核心库中字符串对象的in函数用法完全相同。
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] 字典反序。
in 该函数是重载函数,用于迭代获取字典所有元素,该函数不能设置迭代范围。
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:没有找到成员。
in 该函数是重载函数,用于迭代获取若干结构元素的值。
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。
sys::uniint(a) 转换由字符串生成的唯一的64位整数为扩展类型,该扩展类型可以用o函数输出。例如 uniint[#abc]。
   

1 什么是LuSystem [返回页首]

    LuSystem64.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/lu2/lu2code64.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}, s[i]=0,
  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.89000000000000001秒。共100000个元素。sum=155000000
查询字典耗时9.4e-002秒。共100000个元素。sum=155000000

    (7) 字典中的in函数

    字典是一个可直接存取的双向链表, 虽然仍然可以使用in函数,但用法上与简单序列化对象的in函数有较大区别,in函数中不使用range参数。

        in(p : &next, inc : 2, &a1, &b1, &a2, &b2, &... ...):

    &next:迭代参数next必须初始化为p,即 next = p

    inc,2:常量标识符inc指定迭代增量,迭代增量是一个 非0整数。增量为正表示顺序迭代,增量为负表示反序迭代。inc及迭代增量可以缺省,缺省时增量为1。

    &a1, &b1, &a2, &b2, &... ...:引用方式传递参数时,参数个数必须为偶数,每对参数分别返回 字典成员的“键 - 值”。

    运行错误:1:至少需要2个参数;2: 不可识别对象;3:接收参数要成对;4:迭代参数不可识别(第二个参数);5:增量必须为非0整数 ;6: 内存错误。

    例子:

(: i, p, a, b, c, d, k) =

    p=sys::dict["ab1" : 11, "ab2" : 22, "ab3" : 33, "ab4" : 44, "ab5" : 55, "ab6" : 66, "ab7" : 77],

    i = p,  //迭代参数i初始化为p

    while{ k=in[p : &i,&a,&b,&c,&d],

    o[a," - ",b, " ; ",c," - ",d, " 返回数据个数 = ",k,"\r\n"]};;

    结果(注意:字典建立时总在链表头部插入数据,故顺序与定义时相反):

ab7 - 77 ; ab6 - 66 返回数据个数 = 2
ab5 - 55 ; ab4 - 44 返回数据个数 = 2
ab3 - 33 ; ab2 - 22 返回数据个数 = 2
ab1 - 11 ; ab2 - 22 返回数据个数 = 1

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.56200000000000006秒。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 *** seconds.

sum =

7800000

    (8) 结构中的in函数

    结构是一个线性表,因而可以使用in函数,但用法上与简单序列化对象的in函数稍有区别。另外,注意结构成员的存储顺序与其定义顺序不一定相同。

        in(p : &next, inc : 2, range : 3, 16, &a1, &b1, &a2, &b2, &... ...):

    &a1, &b1, &a2, &b2, &... ...:引用方式传递参数时, 参数个数必须为偶数,每对参数分别返回结构成员和成员的值。

    运行错误:1:至少需要2个参数;2: 不可识别对象;3: 接收参数要成对;4:初始序号必须为整数;5:增量必须为非0整数 ;6:迭代范围必须为整数。

    例子:

(: i, p, a, b) =

    p=sys::struct[#num, #姓名 : "王强", #年龄],

    i=0, while{ in[p : &i, &a, &b], o[a, " ", b, "\r\n"]};;

    结果(注意 #num 和 #年龄 没有赋值,故为 nil):

#姓名 王强
#num nil
#年龄 nil

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__ : @copyAB, #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.85999999999999999秒。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, ...
};

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

    #__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 说明一个指针,在64位平台上,指针为一个数的前8个字节。
%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 说明一个指针,在64位平台上,指针为一个数的前8个字节。
%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-2021,保留所有权利
E-mail: forcal@sina.com
  QQ:630715621
最近更新: 2021年06月22日