AnsiString是Embarcadero C ++ Builder中类型字符串的默认值?

时间:2015-04-17 10:18:54

标签: c++ c++builder unicode-string ansistring

我继承了一个旧的Borland C ++ Builder应用程序,我现在必须将其迁移到一个新的开发工具。建议的方法是使用Embarcadero C ++ Builder,从我最初的测试来看,这似乎是一个相当平滑的过渡。

但我确实有一个问题,我希望有一个简单的解决方案:

应用程序解析大量文本文件。这些文件都是基于ANSI的,并且永远不会改变,因此它是ANSI输入和ANSI输出。我遇到的主要问题是,使用Embarcadero C ++,类型string现在是UnicodeString而不是AnsiString(就像在Borland C ++ Builder中一样)。

在此应用程序中使用Unicode不是一个选项 - 它使用的文件是ANSI格式的。修改代码以使用AnsiString(和类似代码)是可行的,但我不是因为它使用了很多TStringList(和类似的)构造。

所以我的问题是:是否有设置或编译器选项或者我可以用来告诉Embarcadero使用System.AnsiString作为string而不是System.UnicodeString的定义?

这可能是一个长镜头,但是RAD Studio XE(我借用它来做一些测试的旧版本)文档说默认<#34; ,类型string现在是一个Unicode字符串&#34;,这意味着可以更改它。然而,这在当前版本(XE8)的文档中被重新描述,所以......

3 个答案:

答案 0 :(得分:5)

  

我继承了一个旧的Borland C ++ Builder应用程序,我现在必须将其迁移到一个新的开发工具。建议的方法是使用Embarcadero C ++ Builder

是。它们实际上是同一种产品。 Borland创建了一家名为CodeGear的子公司来管理其开发人员工具(Delphi,C ++ Builder等),然后Embarcadero后来收购了CodeGear。

  

我遇到的主要问题是,使用Embarcadero C ++,类型字符串现在是UnicodeString而不是AnsiString(就像在Borland C ++ Builder中一样)。

string(小写s)指的是STL的std::string类,它仍以char为基础。您正在考虑C ++ Builder的System::String别名,它现在映射到System::UnicodeString而不是System::AnsiString(这个更改是在C ++ Builder 2009中进行的,当UnicodeString时介绍)。但是,AnsiString仍然存在,可以直接使用。

  

在此应用程序中使用Unicode不是一个选项 - 它使用的文件是ANSI格式的。

然后不要使用UnicodeString来处理它们。请继续使用AnsiString

  

修改代码以使用AnsiString(和类似的)是可行的,但我宁愿不这样做,因为它使用了很多TStringList(和类似的)构造。

另一方面,那将是一个问题,是的。大多数RTL现在仅支持UnicodeString。因此,必须重新编写使用TStringList的代码,例如使用TList<AnsiString>std::vector<AnsiString>代替(除非代码使用TStringList::(Comma|Delimited)Text属性,在这种情况下,您有更大的重写)。但是,对于AnsiString解析代码,许多较早的基于AnsiString的RTL函数已移至单独的System.AnsiStrings单元,因此您可以将#include <System.AnsiStrings.hpp>添加到代码中它们。

  

所以我的问题是:是否有设置或编译器选项或者我可以用来告诉Embarcadero使用System.AnsiString作为字符串而不是System.UnicodeString的定义?

没有。如果你考虑一下,那将是他们实施的一项重大任务。 RTL / VCL / FMX框架的多个副本,每个支持的OS平台2个。并且许多内部代码必须是IFDEF才能处理Ansi / Unicode处理逻辑之间的差异。因此对他们来说并不是真正可行或具有成本效益(此时为时已晚,特别是考虑到移动操作系统平台不支持AnsiString - 尽管有第三方补丁可用于重新启用它)。

  

这可能是一个长镜头,但是RAD Studio XE(我借用它来做一些测试的旧版本)文档说“默认情况下,类型字符串现在是一个Unicode字符串”,这意味着这可以改变。

不,它不能改变。 RTL / VCL / FMX框架现在是Unicode。但这并不要求您的代码也必须是Unicode。仅在您需要与RTL / VCL / FMX直接交互的位置。其余代码可以根据需要继续使用AnsiString(甚至std::string)。

答案 1 :(得分:1)

可能我有坏消息。他们总是谈论迁移,没有关于快速解决的问题。

http://docwiki.embarcadero.com/RADStudio/XE3/en/Enabling_Applications_for_Unicode http://docwiki.embarcadero.com/RADStudio/XE3/en/Enabling_C%2B%2B_Applications_for_Unicode

嗯......我讨厌Borland的Strings。谁能想到他们从1开始编号而不是0?

答案 2 :(得分:0)

AnsiString -s可以轻松转换为 UnicodeString -s。这就是我处理转换的方式。旧的C ++ Builder 2007代码:

void __fastcall TFormVidya::lbEntData(TWinControl *Control, int Index, AnsiString &Data)
{
    if(FEntNameSto) {
        char *pc;
        int len=FEntNameSto->PeekValue(Index,&pc);
        Data.printf("DB %.*s",len,pc);
    } else Data.sprintf("MOCK %d!",Index);
}

转换为C ++ Builder XE2:

void __fastcall TFormVidya::lbEntData(TWinControl *Control, int Index, UnicodeString &Data)
{
    if(FEntNameSto) {
        char *pc;
        int len=FEntNameSto->PeekValue(Index,&pc);
        AnsiString astr;
        astr.printf("DB %.*s",len,pc);
        Data=astr;
    } else Data.sprintf(L"MOCK %d!",Index);
}

本质是将 AnsiString 分配给 UnicodeString Data=astr;

此外,帮助页面 ms-help://embarcadero.rs_xe2/libraries/System.UnicodeString.html (表示“默认情况下,声明为String类型的变量是UnicodeString”。 ),也说“尽管它的名字,UnicodeString可以代表ANSI字符集字符串和Unicode字符串。”,但我无法使用它。