注册 登录
编程论坛 VFP论坛

DBF表导入UTF-8格式文本时的乱码问题

huasinstamps 发布于 2022-08-09 21:23, 2761 次点击
现在win10保存txt文本文件时是默认用UTF-8格式,当DBF表导入UTF-8格式的txt文本时,中文字符都成了乱码。SDF这个参数好像只适用于ANSI格式的文本。

把文本另存为ANSI格式是可以解决乱码问题,但麻烦了点。请教各位老师和前辈,有没有更好的办法。我用的是VFP6。谢谢!
16 回复
#2
sdta2022-08-09 22:29
发上UTF-8格式的txt文本看看
#3
吹水佬2022-08-10 07:56
转码
数据转码或文件转码
#4
laowan0012022-08-10 13:51
楼上吹版所言极是,遇到乱码可尝试各种可能的转码,测试转码后的文本是否正常,之前我就因为一段文本尝试了各种转换,最终找到了答案
但如果是多次转码的文本就比较麻烦了,需要对不同编码的文本特征有所了解
#5
huasinstamps2022-08-10 17:47
以下是引用sdta在2022-8-9 22:29:00的发言:

发上UTF-8格式的txt文本看看


就是普通的txt文本,内容是用中文字符,在window10直接保存都是UTF-8格式的。用append sdf导入到dbf表后中文就成了乱码。
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2022-8-10 18:00编辑过]

#6
huasinstamps2022-08-10 17:50
以下是引用吹水佬在2022-8-10 07:56:09的发言:

转码
数据转码或文件转码


吹老师数据转码的语句是什么
#7
吹水佬2022-08-10 18:08
回复 6楼 huasinstamps
函数 STRCONV()
#8
huasinstamps2022-08-10 19:17
回复 7楼 吹水佬
这个在vfp6试过不能用,我参考过以前的帖子,据说只在在vfp9中用。
#9
吹水佬2022-08-10 21:16
以下是引用huasinstamps在2022-8-10 19:17:29的发言:

这个在vfp6试过不能用,我参考过以前的帖子,据说只在在vfp9中用。

vfp6的STRCONV()不支持UTF-8转码,可以试试用API或其他脚本写。
API函数:WideCharToMultiByte、MultiByteToWideChar
程序代码:
DECLARE long WideCharToMultiByte IN kernel32 long,long,string,long,string@,long,string@,long
DECLARE long MultiByteToWideChar IN kernel32 long,long,string,long,string@,long
#define CP_UTF8    65001
#define ERROR_NO_UNICODE_TRANSLATION    1113

cUtf8 = AnsiToUtf8("中国")
? Utf8ToAnsi(cUtf8)
RETURN

FUNCTION AnsiToUtf8(cAnsi)
    LOCAL WChar, WCharSize, cUtf8
    WChar = STRCONV(cAnsi+CHR(0),5)
    WCharSize = WideCharToMultiByte(CP_UTF8, 0, WChar, -1, NULL, 0, NULL, 0)
    IF WCharSize==0 OR WCharSize==ERROR_NO_UNICODE_TRANSLATION
        RETURN ""
    ENDIF
    cUtf8 = SPACE(WCharSize)
    IF WideCharToMultiByte(CP_UTF8,0,WChar,-1,@cUtf8,WCharSize,NULL,0) != WCharSize
        RETURN ""
    ENDIF
    RETURN cUtf8
ENDFUNC

FUNCTION Utf8ToAnsi(cUtf8)
    LOCAL WCharSize, buf
    WCharSize = MultiByteToWideChar(CP_UTF8, 0, cUtf8, -1, NULL, 0)
    IF WCharSize==0 OR WCharSize==ERROR_NO_UNICODE_TRANSLATION
        RETURN ""
    ENDIF
    buf = SPACE(WCharSize*2)    && 要足够大
    IF MultiByteToWideChar(CP_UTF8,0,cUtf8,-1,@buf,WCharSize) != WCharSize
        RETURN ""
    ENDIF
    buf = STRCONV(buf,6)
    RETURN LEFT(buf,AT(CHR(0),buf)-1)
ENDFUNC
#10
cssnet2022-08-10 22:38
为什么要重新发明车轮呢?VFP9几乎完全兼容VFP6。
楼主且随手将24年前的老掉牙古董VFP6,换成15年前的老掉牙古董VFP9便是了!——区别也不过就是:可能前者掉了12颗牙,而后者掉了8颗牙,仅仅是“量”的差别而已,根本没有“质”的差别!试问:五十步和一百步,难道有区别么?——具体到这一个STRCONV()函数的小问题,感觉上,在这上头哪怕多花一丁点的气力,便都是纯属多余的!
呵呵。
#11
schtg2022-08-11 06:51
回复 9楼 吹水佬
学习啦,谢谢!
#12
huasinstamps2022-08-11 09:30
回复 9楼 吹水佬
多谢吹老师!

每次发贴求教,论坛上的几位老师都会详尽的回复指点,令我受益匪浅。非常的感谢!

这段代码我得好好研究下。虽然我用VFP也不少年头了,但一直是业余水平。
#13
厨师王德榜2022-08-11 15:32
关于 追加 文本文件入表,我参照前辈的经验,曾经写过完整的一个模型.
这里,愿意分享出来,大家指正.
* 追加前,程序会判断 源文本文件是何种编码格式?
  若是utf8或unicode格式,会询问用户是否需先转换?
* 若用户回答是,则程序先尝试转换,再执行追加动作...

特别说明: 在VFP 9.0下可用.
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2022-8-11 15:38编辑过]

#14
cssnet2022-08-11 16:24
以下是引用厨师王德榜在2022-8-11 15:32:30的发言:
关于 追加 文本文件入表,我参照前辈的经验,曾经写过完整的一个模型.
这里,愿意分享出来,大家指正.
* 追加前,程序会判断 源文本文件是何种编码格式?
  若是utf8或unicode格式,会询问用户是否需先转换?
* 若用户回答是,则程序先尝试转换,再执行追加动作...

特别说明: 在VFP 9.0下可用.


事实上,在我们的软件当中,有一个使用频率最高的函数是:
file2UTF8()
顾名思义:函数功能便是,读入任意编码的TXT文件,并统一转换至UTF-8编码。
这么说吧,今时今日,UTF-8是全宇宙最重要也最常用的文本编码格式,没有之一。
我想象不出,地球上居然还有人会勤劳朴素地特意将UTF-8、Unicode编码转换为ANSI编码来使用!
呵呵呵呵。
一个最简单最浅显的道理:
既然傻瓜都知道,Windows 10/11的记事本,会默认将文本文件存为UTF-8编码格式;那么,即便你闭上眼睛也该想得到,UTF-8编码肯定是当下全宇宙最优秀、最通行也最最最常用的TXT编码格式!难不成,微软吃饱了撑的,非要故意存成UTF-8来为难你?!
#15
厨师王德榜2022-08-11 17:11
谢谢前辈指正,
file2utf8()是不是一个需要声明的api?
有示范吗? 谢谢
#16
cssnet2022-08-11 17:43
以下是引用厨师王德榜在2022-8-11 17:11:54的发言:
谢谢前辈指正,
file2utf8()是不是一个需要声明的api?
有示范吗? 谢谢


不敢当。
file2utf8()只是一个VFP9下的自定义函数。
大致流程:

Function File2UTF8
LPARAMETERS lcFileName
if file(lcFileName)
   lcText = fileToStr(lcFileName)
else
   return ""
endif
*然后Do case逐一测试源TXT的编码格式,并用STRCONV(lcText, 10)之类转换成UTF-8返回
lcBOM = Createbinary(left(lcText, 2))
do case
   case  lcBOM = 0hEFBB  &&'UTF-8'
       return lcText
   case  lcBOM = 0hFFFE  &&'UNICODE'
       return STRCONV(lcText, 10)
   case  lcBOM = 0hFEFF  &&'UNICODE BE'
       * 先将UNICODE大头转小头,即:将奇偶数字节对调(略)……然后再:
       return STRCONV(lcText, 10)    &&Unicode 字符转换为 UTF-8
   Otherwise    &&无BOM,接着猜测源TXT的编码,究竟是:ANSI、UTF-8、Unicode LE还是Unicode BE
      do case
         ...
         ...
      endcase
endcase

抱歉,编写代码的电脑没在身边,凭记忆写的,自己用上边的“转换模板”补足吧。
#17
琅拿度2024-06-16 14:34
以下是引用cssnet在2022-8-11 17:43:38的发言:



不敢当。
file2utf8()只是一个VFP9下的自定义函数。
大致流程:

Function File2UTF8
LPARAMETERS lcFileName
if file(lcFileName)
   lcText = fileToStr(lcFileName)
else
   return ""
endif
*然后Do case逐一测试源TXT的编码格式,并用STRCONV(lcText, 10)之类转换成UTF-8返回
lcBOM = Createbinary(left(lcText, 2))
do case
   case  lcBOM = 0hEFBB  &&'UTF-8'
       return lcText
   case  lcBOM = 0hFFFE  &&'UNICODE'
       return STRCONV(lcText, 10)
   case  lcBOM = 0hFEFF  &&'UNICODE BE'
       * 先将UNICODE大头转小头,即:将奇偶数字节对调(略)……然后再:
       return STRCONV(lcText, 10)    &&Unicode 字符转换为 UTF-8
   Otherwise    &&无BOM,接着猜测源TXT的编码,究竟是:ANSI、UTF-8、Unicode LE还是Unicode BE
      do case
         ...
         ...
      endcase
endcase

抱歉,编写代码的电脑没在身边,凭记忆写的,自己用上边的“转换模板”补足吧。


你好,能补全一下这些代码吗? 有的真不明白怎么做
1