本文节选自《LPC语言基础教程:从零学习游戏开发》,版权归@mudren,欢迎转载,但必须注明来源(mud.ren)。
LPC 语言中的字符串在第二章数据类型中已经做了讲解,这里做个回顾,并补充相关外部函数的使用。
字符串赋值
字符串赋值直接使用以下方法:
string s = "字符串...";
在LPC中赋值时还支持换行这种奇怪的操作,如:
write("
美人卷珠帘,
深坐颦蛾眉。
但见泪痕湿,
不知心恨谁。
");
内行格式会原样输出,具体可以参考示例 2.1.5.c,不过这种用法非主流,C语言下这样用会报错的,个人不推荐使用。如果需要保持字符串内容原样输出,推荐使用 定界符格式,这是很多编程语言都支持的一种格式。以下是使用示例6.4.1.c:
// 示例:6.4.1
int main(object me, string arg)
{
string qr = @EOF
█████████████████████████████████████
█████████████████████████████████████
████ ▄▄▄▄▄ █▀█ █▄▄▄▀ ██▄ █ ▄▄▄▄▄ ████
████ █ █ █▀▀▀█ ▀ ▀█▀▄ ▄█ █ █ ████
████ █▄▄▄█ █▀ █▀▀ ▀▀ ▀▀▄▀█ █▄▄▄█ ████
████▄▄▄▄▄▄▄█▄▀ ▀▄█ █▄█▄█ █▄▄▄▄▄▄▄████
████▄ ▄ █▄ ▄▀▄▀▄ █▀ █ ▀ ▀ ▀▄█▄▀████
████▀█▀▄█▀▄▀██▄█▀██ █ ▀ ▀▄▄ ▀█▀█████
████▀▀▀▄▄▀▄▄ ▄▄█▄▄ ▄ ▄▄ ▀▀▀▀▀▄▄█▀████
████▀▄ ▄ ▄█ █▄ ▄█▄▄██ ▀▄▄▄▀█▄▄▀█████
████ ▄▀▄▄▀▄▀ ▀▀▄ ▄▄▄▄ ▄▀▀█▀█▀▄ █▀████
████ █▄█▄ ▄▀▄█▀▀ █▀ ██▄▀▀ ██▀█▄▀█████
████▄█▄▄▄█▄█ ▀ ▄ ▄█▀▄▄▄ ▄▄▄ ▀ ████
████ ▄▄▄▄▄ █▄█▄█▀██▄▀▄█▄ █▄█ ▄▄▀▀████
████ █ █ █ ▄ ▀▀ ▄▄ ▄▄▀▄▄▄ ▄▀ ▀ ████
████ █▄▄▄█ █ █▄▀ █▄ ██▀ ▄ ▄ █████
████▄▄▄▄▄▄▄█▄▄▄██▄█▄▄▄▄▄████▄▄▄██████
█████████████████████████████████████
█████████████████████████████████████
支付宝扫码打赏
EOF;
printf("%s\n", qr);
return 1;
}
LPC 语言中 定界符格式 要求以 @ + 标志字符开始,以顶格标志字符结束,如以上 EOF,可以换成任何字符串,只要前后一致,且结束的标志字符前面没有任何内容。
@marker
<... text block ...>
marker
字符串合并
字符串合并使用 + 运算符,如果要合并的二个字符串都不是字符串变量,+ 都可以直接省略。如:
write(HIR "字符串输出" NOR);
以上示例中 HIR 和 NOR 都是 ansi.h 中的宏定义,都是字符串常量,和字符串合并时无需 +。
请注意以下内容输出本质上也是多个字符串合并,输出样式和前面换行的不同,这种用法在C语言中也支持,大家应该就陌生:
write(
"美人卷珠帘,"
"深坐颦蛾眉。"
"但见泪痕湿,"
"不知心恨谁。"
);
字符串与字符
在C语言中字符串是字符数组,在LPC语言中没有字符型变量,但也可以类似字符数组的方式取字符串中的字符,str[n]返回的是字符的码位(code point),数据为int型,如:“abcde”[0]返回97,即为字符'a'。
C语言规定,在每一个字符串常量的结尾,系统都会自动加一个字符'\0'作为该字符串的“结束标志符”,系统据此判断字符串是否结束。在LPC语言中类似,字符串"china"长度是5,但实际上在内存中占6个字节,"china"[5]不会报数组越界错误,而是返回0,而"china"[6]才会越界报错。
还可以使用<n从字符串末尾开始取值,str[<x] 相当于 str[strlen(str) - x],比如:"china"[<1]相当于"china[4]",因为字符串是0值结束,"china"[<0]则会返回0,所以如果从尾部开始取第一个字符是<1,即"china[<1]"为"a"。
子字符串操作
在LPC语言中,对字符串取子字符串的操作形式是:
str[n1..n2];
具体用法第二章已经介绍,示例代码为 2.1.5.c,这里复习一下:
n1和n2为子字符串的下标范围,对长度为n的字符串,n1最小值为0,n2最大值为n-1。和取单个字符不同,子字符串下标范围越界不会报错,而是有以下规则:
- 如果n1小于0,那么相当于0
- 如果n2大于n-1,那么相当于n-1
另外还有以下规则:
- 如果
n1 > n-1或n1 > n2,返回空字符串""。 - 和在字符串中取字符类似,子字符串下标加'<'代表从字符串尾部开始。
- 如果直接取值到字符串尾,n2可以省略,
str[n1..]等价于str[n1..<1](注意:n1不可省略)。
提示:请注意str[n..n]和str[n]的区别。
字符串比较
LPC语言中字符串比较可以直接使用比较运算符,也可以使用外部函数 strcmp(),这个外部函数的用法和C语言中的同名函数完全相同。普通比较使用运算符就好,但结合数组排序外部函数 sort_array() 使用时用 strcmp() 更方便。
// 示例:6.4.2
int main(object me, string arg)
{
string *arr = ({"master", "apply", "efun", "mud", "fluffos", "test"});
printf("原始数组 = %O\n", arr);
printf("排序后数组 = %O\n", sort_array(arr, (: strcmp :)));
return 1;
}
部分字符串相关外部函数
字符串处理相关外部函数是比较多的,常用的有:capitalize、crypt、explode、implode、lower_case、oldcrypt、repeat_string、replace_string、sprintf、sscanf、strcmp、stringp、strlen、strsrch、trim、ltrim、rtrim
这些函数具体用法请看:https://wiki.mud.ren/index.php?title=Lpc:Efun
其中 sscanf() 外部函数常用来处理玩家输入指令,具体语法说明如下:
名称
sscanf() - 从一个字符串匹配格式化输入
语法
int sscanf( string str, string fmt, mixed var1, mixed var2 ... );
描述
以格式 `fmt` 分析字符串 `str`,返回值是匹配字符串的格式定义符数量。`fmt` 可以包含使用 `%d` 或 `%s` 分隔的字符串,每一个 `%d` 和 `%s` 按顺序对应一个变量参数 `var1`、`var2`...。`%d` 读入整数到变量,`%s` 读入字符串到变量。* 也可以用在格式定义符中(如 %*d 和 %*s),表示忽略对应的内容(不分配给变量)。
LPC语言中的 sscanf() 函数和C语言中的同名函数功能类似,但又稍有不同,一方面不需要像C语言一样对普通变量使用取地址运算符 &,另一方面在LPC语言中 sscanf(str, "%s %s", str1, str2) 会把第一个单词分配给变量str1,剩余部分分配给str2,而在C语言中str2只会是第二个单词。请注意 %s%s 是不能使用的。
外部函数 crypt() 用来加密字符串,常用来存储玩家密码,fluffos 和 mudos 的加密方式不同,如果要兼容,只能使用 oldcrypt() 外部函数加密。具体语法说明如下:
名称
crypt() - 加密一个字符串
语法
string crypt( string str, string seed );
描述
以字符串 `seed` 为种子加密字符串 `str`,如果 `seed` 是 0,使用随机种子。
如果以字符串 str 加密后的字符串做为种子继续对字符串 str 加密,返回字符串还是这个种子。用 crypt() 函数验证密码的示例:
if (crypt(pwd, crypt_pwd) == crypt_pwd)
{
// ...
}
以上示例中 pwd 为玩家输入的密码,crypt_pwd 为系统保存的加密密码。