【发布时间】:2020-12-01 10:45:24
【问题描述】:
在使用 CLANG 编译器时,我遇到了 Embarcadero C++ Builder 的一个非常奇怪的行为。
例子很简单:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
std::wostringstream woss;
woss << std::wstring(L"N°1: ") << (int) 1234;
woss << '\r' << '\n';
woss << std::wstring(L"N°2: ") << (float) 12.34;
Memo1->Lines->Add( woss.str().c_str() );
std::ostringstream oss;
oss << std::string("N°3: ") << (int) 4567;
oss << '\r' << '\n';
oss << std::string("N°4: ") << (float) 45.67;
Memo1->Lines->Add( oss.str().c_str() );
}
只要代码是用 Borlands 经典编译器编译的,它就会准确地打印出我所期望的:
- N°1:1234
- N°2:12.34
- N°3:4567
- N°4:45.67
但是,一旦我切换到 CLANG 编译器 (bcc32c)(通过在设置对话框中取消选中“使用经典编译器”),我就会得到以下结果:
- N°1:1234
- N°2:-0
- N°3: 4567
- N°4:-0
编辑:请忽略 std::string 的问题 - 重要的是错误的浮点数。
(不仅浮点数被压碎,对常规 std::string 的解释似乎也存在问题。)
bcc32c 有什么问题,我该如何处理?
我正在为 WIN32 目标平台使用 Embarcadero C++ Builder 10.0 (Seattle)。
谢谢
【问题讨论】:
-
这可能是编码的问题,例如UTF-8 与 ??? (ANSI或其他)。字符串文字中的字符具有源代码的编码。如果编译器为您的输出使用不同的编码,那么......不确定这与
floats 有什么关系,但它可以解释N°3。 -
oss << '\r' << '\n';仅使用oss << '\n';。\n将由 C 运行时自动转换为每个平台的正确换行符。并尝试仅对新编译器使用 UTF-8 编码。可能 Embarcadero 太老了,以至于它使用“ANSI”代码页 -
关于
N°3的详细信息:°在 Windows-1252 中有代码 176 ('\xb0'),但在 UTF-8:"\xc2\xb0"中是一个两字节序列。现在,这两个字节再次出现在 Windows-1252 中:°。所以,我假设你的源代码中的字符串文字是用 UTF-8 编码的,但输出完成后将其解码为 Windows-1252。 -
我在 Windows 中使用 G++ 获得
N�1: 1234 N�2: 12.34 N°3: 4567 N°4: 45.67。 (虽然没有那个古老的__fastcall东西,但这不应该改变任何东西) -
正确的问题是:你的源文件是什么编码的?您输出使用的控制台(或其他)是什么编码?如何让双方“合作”?也许 ICU 或 boost 的 UTF 东西是这里的答案?
标签: c++ clang c++builder ostringstream