使用 FreePascal 在 Lazarus 中将 AnsiString 转换为 UnicodeString
Convert AnsiString to UnicodeString in Lazarus with FreePascal
我在这里找到了类似的主题,但其中 none 已经解决了我的问题,所以我在新线程中提问。
几天前,我更改了保存我正在开发的应用程序首选项的格式,从 INI 更改为 JSON。
我为此使用了 jsonConf 单元。
我用来在文件中保存键值对的代码示例如下所示。
Procedure TMyClass.SaveSettings();
var
c: TJSONConfig;
begin
c:= TJSONConfig.Create(nil);
try
c.Filename:= m_settingsFilePath;
c.SetValue('/Systems/CustomName', m_customName);
finally
c.Free;
end;
end;
在我的代码中,m_customName是一个AnsiString类型的变量。 TJSONConfig.SetValue 过程要求键和值都是 UnicodeString 类型。应用程序编译正常,但我收到这样的警告
Warning: Implicit strung type conversion from "AnsiString" to "UnicodeString".
有些消息警告称可能会丢失数据。
当然我可以把所有的东西都改成UnicodeString类型,但这太冒险了。到目前为止,通过忽略这些警告我没有看到任何问题,但它们一直出现并且可能会在另一台 PC 上引起问题。
我该如何解决这个问题?
为了避免警告,请进行显式转换,因为这样您就可以告诉编译器您知道自己在做什么(我希望...)。在 c.SetValue
的情况下,预期类型是 Unicodestring (UTF16),m_customname
应该声明为 string
除非有充分的理由做不同的事情(见下文),否则你可能会触发不需要的内部转换。
Lazarus 中的 string
默认是 UTF8 编码的。所以UTF8到Unicode的转换可以使用函数UTF8Decode()
,或者UTF8ToUTF16()
(unit LazUtf8)。
var
c: TJSONConfig;
m_customName: String;
...
c.SetValue('/Systems/CustomName', UTF8Decode(m_customName));
你在上面说键值对在一个文件中。然后转换取决于文件的编码。通常我在一个好的文本编辑器中打开文件并在某处找到编码 - 例如 NotePad++,在状态栏的右上角显示编码的名称。假设编码是代码页 1252 (Latin-1)。这些是反字符串,因此,您可以将从文件中读取的字符串声明为 ansistring
。因为 UTF8 字符串在 Lazarus 中很常见,所以没有从 ansistring 到 Unicode 的直接转换,您必须先转换为 UTF8。在单元 lconvencoding 中,您会发现许多各种编码之间的转换例程。 Select CP1252toUTF8() 转到UTF8,然后应用UTF8Decode() 最终得到Unicode。
var
c: TJSONConfig;
m_customName: ansistring;
...
c.SetValue('/Systems/CustomName', UTF8Decode(CP1252ToUTF8(m_customName)));
FreePascal 编译器 3.0 可以使用带有预定义编码的字符串自动处理其中的许多转换。但我认为显式转换非常清楚,可以看到发生了什么。而且 fpc3.0 仍然会发出您想避免的警告...
我在这里找到了类似的主题,但其中 none 已经解决了我的问题,所以我在新线程中提问。
几天前,我更改了保存我正在开发的应用程序首选项的格式,从 INI 更改为 JSON。
我为此使用了 jsonConf 单元。
我用来在文件中保存键值对的代码示例如下所示。
Procedure TMyClass.SaveSettings();
var
c: TJSONConfig;
begin
c:= TJSONConfig.Create(nil);
try
c.Filename:= m_settingsFilePath;
c.SetValue('/Systems/CustomName', m_customName);
finally
c.Free;
end;
end;
在我的代码中,m_customName是一个AnsiString类型的变量。 TJSONConfig.SetValue 过程要求键和值都是 UnicodeString 类型。应用程序编译正常,但我收到这样的警告
Warning: Implicit strung type conversion from "AnsiString" to "UnicodeString".
有些消息警告称可能会丢失数据。
当然我可以把所有的东西都改成UnicodeString类型,但这太冒险了。到目前为止,通过忽略这些警告我没有看到任何问题,但它们一直出现并且可能会在另一台 PC 上引起问题。
我该如何解决这个问题?
为了避免警告,请进行显式转换,因为这样您就可以告诉编译器您知道自己在做什么(我希望...)。在 c.SetValue
的情况下,预期类型是 Unicodestring (UTF16),m_customname
应该声明为 string
除非有充分的理由做不同的事情(见下文),否则你可能会触发不需要的内部转换。
Lazarus 中的 string
默认是 UTF8 编码的。所以UTF8到Unicode的转换可以使用函数UTF8Decode()
,或者UTF8ToUTF16()
(unit LazUtf8)。
var
c: TJSONConfig;
m_customName: String;
...
c.SetValue('/Systems/CustomName', UTF8Decode(m_customName));
你在上面说键值对在一个文件中。然后转换取决于文件的编码。通常我在一个好的文本编辑器中打开文件并在某处找到编码 - 例如 NotePad++,在状态栏的右上角显示编码的名称。假设编码是代码页 1252 (Latin-1)。这些是反字符串,因此,您可以将从文件中读取的字符串声明为 ansistring
。因为 UTF8 字符串在 Lazarus 中很常见,所以没有从 ansistring 到 Unicode 的直接转换,您必须先转换为 UTF8。在单元 lconvencoding 中,您会发现许多各种编码之间的转换例程。 Select CP1252toUTF8() 转到UTF8,然后应用UTF8Decode() 最终得到Unicode。
var
c: TJSONConfig;
m_customName: ansistring;
...
c.SetValue('/Systems/CustomName', UTF8Decode(CP1252ToUTF8(m_customName)));
FreePascal 编译器 3.0 可以使用带有预定义编码的字符串自动处理其中的许多转换。但我认为显式转换非常清楚,可以看到发生了什么。而且 fpc3.0 仍然会发出您想避免的警告...