我使用delphi 7。
我需要逐行读取一个utf-8文件,每行包含一个单词及其权重(一个数字) 所以我需要读取每一行,然后用分隔符(tab char)划分一行,并将其保存在内存中。
所以,
1)是否有一个库可以在Delphi中使用utf-8文件(可能是第3个聚会)
2)功能是否可以使用宽字符串运行?我使用PosEx。那么,如果他们不这样做,您是否也可以链接到第三方图书馆以使用宽带?
答案 0 :(得分:4)
如果您正在处理的是真正的UTF-8,那么就阅读和处理它们而言,您不需要任何特殊的东西。您应该能够将它们视为pchar或甚至是普通的Delphi 7字符串。如果您尝试在某种消息框中显示内容,则可能需要进行一些转换。例如,如果字符串包含超过127(0x7f)的任何字节值,我不相信Delphi 7消息框方法会正确显示UTF-8字符串。对于类似的东西,你需要转换为UTF-16并调用Windows API MessageBoxW或类似的东西。但是,在许多情况下,UTF-8字符串可以与单字节ANSI字符串相同。
我认为UTF-8通常被称为“宽带”。我可能错了,但我认为这通常意味着UTF-16。
答案 1 :(得分:2)
如果您的文件编码为UTF-8,并且您要查找的字符是ASCII,那么根本不需要使用WideString
。 ASCII是UTF-8的子集,并且保证任何ASCII字符不会干扰UTF-8中其他字符使用的特殊编码。数字字符0
到9
和制表符都是ASCII。
JCL附带了各种用于处理Unicode的函数和类,如果您发现确实需要使用它们。
答案 2 :(得分:1)
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所说,作为实现UTF字符串操作的免费库,JCL是一个很好的起点。
答案 3 :(得分:1)
如果您的大部分输入都是UTF-8,则可能值得将启动时的代码页从“默认”更改为utf8(代码页65001)。这将使所有ansistring->宽带转换有效地变为无损utf-8-> utf-16。
使用D7,您将需要一组所谓的“unicode”组件,这些组件基于winapi -W功能。 Delphi自己的组件仅在分水岭D2009版本中执行此操作,该版本将默认字符串类型切换为UTF-16。
如果您想大量投资Unicode支持,升级可能是明智之举
答案 4 :(得分:0)
您可以通过其LoadFrom ...()方法将文件原样读取到正常的TStringList中,然后根据需要循环遍历列表。如果不能同时将整个文件加载到内存中,则可以使用TFileStream打开文件,然后使用TStreamReader.ReadLine()方法逐行读取流。
如果你需要将给定的UTF-8序列解码为UTF-16进行处理,那么我建议直接使用Win32 API MultiByteToWideChar()函数,因为RTL的UTF8Decode()函数具有破坏的UTF-8实现在较旧的Delphi版本中(不确定D7,但它肯定在D6中)。
关于加载方法的好处是它们在D2009及更高版本中都是编码感知的,这意味着如果你曾经升级过,你可以做一些非常小的代码更改来告诉RTL数据是UTF -8,它会自动将它解码为UTF-16,然后其余的处理代码可以保持不变(假设您没有做任何特定于Ansi的事情)。