明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: weilu

[提问] 如何得到TXT文件的编码格式信息?

[复制链接]
发表于 2023-4-6 09:24:14 | 显示全部楼层
以前碰巧玩过,如果没记错的话,UNICODE前面两个字节是文件头,可以判断,ASCII和UTF-8就没有文件头了,没法简单的精确判断,毕竟如果纯英文,ASCII和UTF-8是一样的。
 楼主| 发表于 2023-4-6 11:48:54 | 显示全部楼层
mikewolf2k 发表于 2023-4-6 09:24
以前碰巧玩过,如果没记错的话,UNICODE前面两个字节是文件头,可以判断,ASCII和UTF-8就没有文件头了,没 ...

用lisp怎么查看文件头?
发表于 2023-4-6 12:38:40 | 显示全部楼层
weilu 发表于 2023-4-5 14:40
文件就是普通的windows操作系统下创建的UTF-8编码格式的TXT文件,用read-line读后,中文字符都是乱码。

很正常,read-line 是以 ANSI 编码格式读取的,如果是 UTF-8 的编码格式,结果出来就是乱码。
发表于 2023-4-6 15:19:12 | 显示全部楼层
weilu 发表于 2023-4-6 11:48
用lisp怎么查看文件头?

我是C#读取字节,不是LISP。
 楼主| 发表于 2023-4-6 15:32:22 | 显示全部楼层
vormittag 发表于 2023-4-6 12:38
很正常,read-line 是以 ANSI 编码格式读取的,如果是 UTF-8 的编码格式,结果出来就是乱码。

之前在论坛上看到有人讲,高版本CAD LISP的open函数可以设置编码格式?
发表于 2023-4-6 16:17:42 | 显示全部楼层
UTF-8编码的文本文档,有的带有BOM (Byte Order Mark, 字节序标志),即0xEF, 0xBB, 0xBF,有的没有。Windows下的txt文本编辑器在保存UTF-8格式的文本文档时会自动添加BOM到文件头。在判断这类文档时,可以根据文档的前3个字节来进行判断。然而BOM不是必需的,而且也不是推荐的。对不希望UTF-8文档带有BOM的程序会带来兼容性问题,例如Java编译器在编译带有BOM的UTF-8源文件时就会出错。而且BOM去掉了UTF-8一个期望的特性,即是在文本全部是ASCII字符时UTF-8是和ASCII一致的,即UTF-8向下兼容ASCII。

在具体判断时,如果文档不带有BOM,就无法根据BOM做出判断,而且IsTextUnicode API也无法对UTF-8编码的Unicode字符串做出判断。那在编程判断时就要根据UTF-8字符编码的规律进行判断了。

UTF-8是一种多字节编码的字符集,表示一个Unicode字符时,它可以是1个至多个字节,在表示上有规律:

1字节:0xxxxxxx
2字节:110xxxxx 10xxxxxx
3字节:1110xxxx 10xxxxxx 10xxxxxx
4字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

这样就可以根据上面的特征对字符串进行遍历来判断一个字符串是不是UTF-8编码了。应该指出的是UTF-8字符串的各个字节的取值有一定的范围,并不是所有的值都是有效的UTF-8字符,但是一般的应用的情况下这样的判断在对足够长的字符串及是比较精确了,而且实现也比较简单。具体的字节取值范围可以参见"Unicode Explained"一书中的6.4.3。另外BOM本身也符合3字节UTF-8字符编码规律
发表于 2023-4-7 16:21:08 | 显示全部楼层
写个函数判断一下(有BOM的自行处理):
  1. (defun Is_UTF8_No_BOM (str / is_UTF8 loop)
  2.   (setq is_UTF8 t
  3.         loop t
  4.   )
  5.   (while (and str loop)
  6.      (cond ((< (car str) 128) (setq str (cdr str)))  ;; 小于0x80为ACSCII字符
  7.            ((< (car str) 192) (setq is_UTF8 nil loop nil))  ;;(11000000) 介于0x80和0xC0之间的为无效的UTF-8字符
  8.            ((< (car str) 224)  ;;此范围为2字节UTF-8字符
  9.               (if (<= (length str) 1)
  10.                   (setq is_UTF8 nil loop nil)
  11.                   (if (/= (logand (cadr str) 192) 128) ;;_else  (str[1] & 0xC0 != 0x80)
  12.                       (setq is_UTF8 nil loop nil) ;;不符合
  13.                       (setq str (cddr str))  ;;_else 继续
  14.                   )
  15.               )  ;;if
  16.            )
  17.            ((< (car str) 240)  ;;(11110000) 此范围为3字节UTF-8字符
  18.               (if (<= (length str) 2)
  19.                   (setq is_UTF8 nil loop nil)
  20.                   (if (or (/= (logand (cadr str) 192) 128) (/= (logand (caddr str) 192) 128)) ;;_else  
  21.                       (setq is_UTF8 nil loop nil) ;;不符合
  22.                       (setq str (cdddr str))  ;;_else 继续
  23.                   )
  24.               )        
  25.            )
  26.            (t (setq is_UTF8 nil loop nil))
  27.      )
  28.   )
  29.   is_UTF8
  30. )
 楼主| 发表于 2023-4-10 13:53:02 | 显示全部楼层
小菜123 发表于 2023-4-7 16:21
写个函数判断一下(有BOM的自行处理):

请问如何获得所需要的str?
发表于 2023-4-10 20:51:36 | 显示全部楼层
原来的帖子,这次一并完善一下:
http://bbs.mjtd.com/thread-185530-1-1.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-15 15:08 , Processed in 0.182592 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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