4

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

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

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

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

所以我的问题是:是否有一个设置或编译器选项或我可以用来告诉 EmbarcaderoSystem.AnsiString用作定义string而不是的东西System.UnicodeString

这可能是一个长镜头,但 RAD Studio XE(这是我借来进行一些测试的旧版本)文档说“默认情况下,类型string现在是 Unicode 字符串”,这意味着这可以是改变了。但是,当前版本(XE8)的文档中对此进行了改写,因此...

4

3 回答 3

6

我继承了一个旧的 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(该更改是在UnicodeString引入时在 C++Builder 2009 中进行的)。但是,AnsiString仍然存在并且可以直接使用。

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

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

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

另一方面,这将是一个问题,是的。大多数 RTLUnicodeString现在只支持。因此TStringList必须重写代码 using ,例如使用TList<AnsiString>orstd::vector<AnsiString>代替(除非代码正在使用TStringList::(Comma|Delimited)Text属性,在这种情况下您需要进行更大的重写)。但是,为了AnsiString解析代码,许多AnsiString基于旧的 RTL 函数被移动到一个单独的System.AnsiStrings单元,因此您可以添加#include <System.AnsiStrings.hpp>到您的代码中以访问它们。

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

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

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

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

于 2015-04-17T20:52:35.940 回答
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 编号的?!

于 2015-04-17T10:35:30.537 回答
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 字符串。 ”,但我无法使用它。

于 2016-02-21T22:11:27.547 回答