【问题标题】:Convert AnsiString to UnicodeString in Lazarus with FreePascal使用 FreePascal 在 Lazarus 中将 AnsiString 转换为 UnicodeString
【发布时间】:2016-09-27 07:13:09
【问题描述】:

我在这里找到了类似的主题,但没有一个能解决我的问题,所以我在一个新线程中提问。

几天前,我将保存我正在开发的应用程序的首选项的格式从 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 上引起问题。

我该如何解决这个问题?

【问题讨论】:

  • 你为什么不到处使用string
  • 然后它会抱怨'警告:从“ShortString”到“UnicodeString”的隐式字符串类型转换'。
  • 为什么stringShortString 的别名?我不明白你为什么要使用ShortStringAnsiString
  • 我认为前进的方向是让您停止在黑暗中这样做,并了解 FPC 中如何处理字符串。试图在没有获得知识的情况下继续前进是不可能有成效的。
  • 我只使用 Lazarus/fpc,但这个问题对我来说仍然很混乱。对此进行了很多讨论。我的印象是当前版本 1.6 及更高版本使用“字符串”透明地处理所有这些。但是要问的人真的在这里:forum.lazarus.freepascal.org/index.php?action=forum 或在邮件列表中,但邮件列表与大多数开发相关。

标签: lazarus freepascal ansistring


【解决方案1】:

为了避免警告,请进行显式转换,因为这样可以告诉编译器您知道自己在做什么(我希望...)。如果 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。因为 UTF8 字符串在 Lazarus 中很常见,所以没有从 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 仍然会发出您想要避免的警告...

【讨论】:

  • 谢谢。我想知道的是这个答案。将 AnsiString 显式转换为 UnicodeString: UTF8Decode 将 UnicodeString 显式转换为 AnsiString: UTF8Encode 感觉名称应该反过来。我没有抱怨。
  • 我与你同在 - 从来没有对这些名字感到幸运,而是更喜欢 UTF8ToUTF16 和 UTF16ToUTF8 函数。
猜你喜欢
  • 2015-01-09
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多