Delphi ReadLn使用WideString(utf-8文件)

Delphi ReadLn使用WideString(utf-8文件),delphi,utf-8,delphi-7,widestring,Delphi,Utf 8,Delphi 7,Widestring,我使用Delphi7 我需要逐行读取一个utf-8文件,每行包含一个单词及其权重(一个数字) 所以我需要读取下一行,然后用一个分隔符(tabchar)分隔一行,并将其保存在内存中 所以 1) Delphi中是否有可以使用utf-8文件的库(可能是第三方) 2) widestring的功能运行正常吗?我用PosEx。因此,如果他们不愿意,您是否也可以提供一个指向第三方库的链接以使用WideString?如果您正在处理的是真正的UTF-8,那么您就不需要任何特殊的内容来读取和处理它们。您应该能够将它

我使用Delphi7

我需要逐行读取一个utf-8文件,每行包含一个单词及其权重(一个数字) 所以我需要读取下一行,然后用一个分隔符(tabchar)分隔一行,并将其保存在内存中

所以

1) Delphi中是否有可以使用utf-8文件的库(可能是第三方)


2) widestring的功能运行正常吗?我用PosEx。因此,如果他们不愿意,您是否也可以提供一个指向第三方库的链接以使用WideString?

如果您正在处理的是真正的UTF-8,那么您就不需要任何特殊的内容来读取和处理它们。您应该能够将它们视为pchar,甚至视为普通的Delphi7字符串。如果试图在某种消息框中显示内容,则可能需要进行一些转换。例如,如果字符串包含超过127(0x7f)的任何字节值,我认为Delphi7消息框方法不会正确显示UTF-8字符串。对于类似的东西,您需要转换为UTF-16并调用WindowsAPI MessageBoxW或类似的东西。但是,在许多情况下,UTF-8字符串可以与单字节ANSI字符串一样处理


我不认为UTF-8通常被称为“widestring”。我可能错了,但我认为这通常意味着UTF-16

如果您的文件编码为UTF-8,并且您要查找的字符是ASCII,则根本不需要使用
WideString
。ASCII是UTF-8的子集,任何ASCII字符都保证不会干扰UTF-8中用于其他字符的特殊编码。数字字符
0
9
和制表符都是ASCII码


如果您发现确实需要使用Unicode,则会提供用于处理Unicode的各种函数和类。

WideString是一种UTF-16实现(与COM BSTR兼容的实现),它无法存储UTF-8字符串,如果您指定一个8位字符串,它将转换为UTF-16。但是,除非明确使用正确的转换函数,否则Delphi将使用当前代码页解释8位字符串

UTF-8字符串可以存储在Delphi AnsiString(Delphi 7中的默认字符串类型)中,但字符串操作函数是为ANSI代码页而不是UTF-8设计的。区别在于UTF-8是一个多字节字符集。但对于前127个ANSI字符,编码一个给定的“字符”需要不止一个字节,而许多ANSI代码页(尤其是欧洲语言的代码页)只需要一个字节,只编码255个“字符”(而UTF-8可以编码整个Unicode集)


如果只是查找制表符AFAIK,可以使用简单的AnsiString,但必须确保可能需要查找的$80以上的任何字节都不是多字节序列的一部分。如果您有更复杂的处理需求,那么找到处理UTF-16字符串的库可能比UTF-8更容易。正如Rob Kennedy所说,JCL作为实现UTF字符串操作的免费库是一个很好的起点。

如果您的大多数输入是UTF-8,那么在启动时将代码页从“默认”更改为utf8(代码页65001)可能是值得的。这将使所有ansistring->widestring转换有效地成为无损utf-8->utf-16

使用D7,您将需要一组所谓的“unicode”组件,这些组件基于winapi-W函数。Delphi自己的组件仅在Water分水岭D2009版本中将默认字符串类型切换为UTF-16时才执行此操作


如果您想大力投资Unicode支持,升级可能是一件明智的事情

您只需通过LoadFrom…()方法将文件原样读入普通的TStringList,然后根据需要循环浏览列表即可。如果不能同时将整个文件加载到内存中,则可以使用TFileStream打开文件,然后使用TStreamReader.ReadLine()方法逐行读取流

如果需要将给定的UTF-8序列解码为UTF-16进行处理,那么我建议直接使用Win32 API MultiByteToWideChar()函数,因为RTL的UTF8Decode()函数在较旧的Delphi版本中有一个中断的UTF-8实现(不确定D7,但在D6中肯定有)

这两种加载方法的优点是,它们在D2009和更高版本中都支持编码,这意味着如果您升级,您可以进行一些非常小的代码更改,告诉RTL数据是UTF-8,它会自动将其解码为UTF-16,然后处理代码的其余部分可以保持不变(假设您没有做任何特定于Ansi的事情)