明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 5556|回复: 12

[经验] lisp的中文陷阱

  [复制链接]
发表于 2013-12-26 05:20 | 显示全部楼层 |阅读模式
本帖最后由 llsheng_73 于 2013-12-26 05:45 编辑

read函数算是用得比较多的函数之一
经常被用于对read-line得到的字符串直接构表,不用说其效率那是相当高的
下边的while是比较常见的用法
(setq f(getfiled"打开数据文件" "" "txt"4))
(setq f(if(findfile f)(open "文件名" "r")))
(while (setq a(read-line f))
    (setq a(read(strcat"("a")")))
    (setq b(cons a b)))
(close f)
(setq b(reverse b))
比如这样读取文本文件中的坐标点组成一个坐标列表,在没有空行的情况下基本这样就行了,我也基本这样读取坐标数据等,这个当然不会出问题。
但我想提醒一下新手的是,最好不要用   (setq b(read(strcat"("a")")))去处理包含中文甚至可能非标准ANSI编码的字符的内容或者全是数字但位数很多的数字串,比如一个文件包含很多行姓名和身份证号,先(setq a(read-line f))是不会出问题的,但接下来的一句 (setq b(read(strcat"("a")")))本来希望得到一个表(姓名 身份证),表是能得到,但是,它的内容不会是我们想要的,首先身份证号有18位,这样read的结果它会因为超过整数表达范围而变成一个科学计数法表示的实数通常会成为5.10824e+017,这个问题一般能够想到然后想出办法避免它。
但是中文内容有时它有可能会被弄错,这就不一定会被发现了,我认为只有上过当才可能发现它,下边是我前几天遇到的,当时也差不多按上边那段程序读取一个镇、村的行政表,结果十九个乡镇,不管怎么办总是有几个会被弄错,下边是我去逐步运行读取文件的过程得到它出错的位置,总共有好几处
(setq b(read-line f))
"来复镇\t九缸村"
(read(strcat"("b")"))
(巩固村 九缸村)
这是我在程序中碰到的事情,以前也碰到过一次,当时就是读取姓名和身份证号,结果用(assoc 姓名 lst)得不到结果的时候才发现上了当,程序每次都会把它弄错,而单独给它这么个内容去测试时它却又不会错,所以我只能说在循环过程中,它有一定机率会把中文内容弄成别的,上过几次当之后,再读取文本文件组表时,我不得不老老实实的去找它的分隔符然后substr,这样虽然代码明显增多,效率也下降了些,但好在保险,算是不得已而为之吧。

另外,不知道从什么时候开始,有人热衷于把变量名弄成中文名了,说什么意思清楚明白等等,反正好处一大堆,但是,这样的命名也许个人会觉得直白好理解容易看懂,但CAD它并不一定会给你看懂的,它非ANSI标准编码的字符指定为符号的时候,它很可能会出错的,如果不会出错,那前边我碰到的情况它也不应该出现才对,但不巧的是它会出现,也有人已经发帖问是怎么回事了
赋值给两个不同名称的中文变量,结果却视为同一变量
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=101962&fromuid=202795
有人说是变量名超过6个字符,但我觉得这不是根本原因,如果把其中的中文变量名换成半角英文字母,估计应该还可以更长些都能区分,当然这个长度又要受CAD版本或者系统限制。但是用中文字符作为符号时,虽然长度远远不到长度限制,但它也很可能被混淆。
所以,个人建议,处理非标准ANSI编码的字串时,特别是读取文本文件,最好不要图简单省事直接进行read,该找分隔符位置取子串还得老老实实的去取子串,不然一个read之后出了错可能还不知道(因为这错误它并不一定会出现),另外程序中还是最好别用中文去命名变量、函数之类的,写着累就不说了,看着也累(实在怕不理解或者哪天忘了哪个变量是什么意义,完全可以在语句后边加;;再说明),更关键的是它要出错恐未必能很快找到原因。


下边我附上当时的文件,有兴趣的可以去读取一下会不会完全正解读出


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2013-12-26 07:36 | 显示全部楼层
支持 帮顶 早上好
发表于 2013-12-26 08:13 | 显示全部楼层
想要彻底的支持中文,还得要桌子公司下功夫。
猫版早早退出中文LISP也是正确的。
发表于 2013-12-26 08:59 | 显示全部楼层
(setq filename "e:\\行政村.txt")
(setq file (open filename "r"))
(setq out '())
(while (setq a (read-line file))
  (setq out (cons a out))
  )
(close file)
(setq out (reverse out))
(setq out (mapcar '(lambda(x)
                     (setq i (vl-string-search "\t" x))
                     (list (substr x 1 i)
                           (substr x (+ i 2)))
                     )
                  out
                  )
      )
发表于 2013-12-26 10:39 | 显示全部楼层
这应该是Auto公司故意这么做的,想让我们更多地依赖于他们,好垄断我们的CAD产业、
发表于 2013-12-26 19:04 | 显示全部楼层
本帖最后由 xyp1964 于 2013-12-26 19:05 编辑
  1. (setq lst (xyp-txt2list "行政村.txt")
  2.       lst (mapcar '(lambda (x) (xyp-String-Subst " " "\t" x)) lst)
  3. )
 楼主| 发表于 2013-12-26 23:13 | 显示全部楼层
谢谢lijiao 和院长,对于那个文件我只是想说明如果用(read(strcat"(" a ")"))这亲的方式去处理它会乱来,目的告诫大家处理中文字符时不要图简单省事,说不定什么时候就出个乱子的
发表于 2013-12-27 00:07 来自手机 | 显示全部楼层
又多学内容了,,,其实我在整图斑面积汇总,也是,比如现在的新代码023读完了就变成23前面的零会消失,哎。
发表于 2015-3-27 10:24 | 显示全部楼层
一直没有使用中文变量的习惯,切换输入法太麻烦。
发表于 2015-3-27 15:34 | 显示全部楼层
我在win7 32位05版下试

Command: (setq b "来复镇\t九缸村")
"来复镇\t九缸村"

Command: (read(strcat"("b")"))
(来复镇 九缸村)

怎么不是你说的返回=》(巩固村 九缸村)????
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-2 09:10 , Processed in 0.229570 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表