我在这里找到了类似的主题,但是他们都没有我的问题的解决方案,所以我在一个新的线程中问它。
几天前,我更改了我正在开发的应用程序首选项的格式,从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出现问题。
我该如何解决这个问题?
答案 0 :(得分:3)
为了避免警告,请进行显式转换,因为这样您告诉编译器您知道自己在做什么(我希望......)。如果c.SetValue
期望的类型是Unicodestring(UTF16),m_customname
应该声明为string
,除非有充分的理由做不同的事情(见下文),否则你可能会触发不需要的内部转换。
默认情况下,Lazarus中的string
是UTF8编码的。因此,您可以使用函数UTF8Decode()
进行从UTF8到Unicode的转换,或UTF8ToUTF16()
(单位 LazUtf8 )。
var
c: TJSONConfig;
m_customName: String;
...
c.SetValue('/Systems/CustomName', UTF8Decode(m_customName));
您在上面说过,键值对位于文件中。然后转换取决于文件的编码。通常我在一个好的文本编辑器中打开文件并在某处找到编码 - 例如,NotePad ++在状态栏的右下角显示编码的名称。假设编码是代码页1252(Latin-1)的编码。这些是ansistrings,因此,您可以将从文件中读取的字符串声明为ansistring
。因为在Lazarus中UTF8字符串是如此常见,所以没有从ansistring到Unicode的直接转换,您必须首先转换为UTF8。在 lconvencoding 单元中,您可以在各种编码之间找到许多转换例程。选择CP1252toUTF8()转到UTF8,然后应用UTF8Decode()最终获得Unicode。
var
c: TJSONConfig;
m_customName: ansistring;
...
c.SetValue('/Systems/CustomName', UTF8Decode(CP1252ToUTF8(m_customName)));
FreePascal编译器3.0可以使用具有预定义编码的字符串自动处理许多这些转换。但我认为明确的转换非常清楚,看看发生了什么。并且fpc3.0仍然会发出你想要避免的警告......