2016-02-12 46 views
2

我尝试使用带有Unicode字符的TJSONObject类,但解析后得到????而不是原始文本。用TJSONObject解析Unicode文本返回'????'

的简单的问题是:

UnicodeString doc = L"{\"alias\":\"Test ЮРИСЛАВ\"}"; 
ShowMessage(doc); 
TJSONObject* jo=new TJSONObject(); 
jo->Parse(BytesOf(doc), 0); 
ShowMessage(jo->ToString()); 

第一ShowMessage显示正确的文字:ЮРИСЛАВ
但解析所述第二ShowMessage后显示????代替ЮРИСЛАВ

我做错了什么?

+0

尝试使用'String' insted的的用于'doc'变量的'UnicodeString'或使用'UTF8Encode()'函数 – Marusyk

+0

我做到了,但是结果相同 – kokokok

回答

1

更改为这样的事情:

jo = (TJSONObject*) TJSONObject::ParseJSONValue(TEncoding::UTF8::GetBytes(doc), 0); 

您应该将Unicode文本转换成UTF8解析它。

+1

您可以直接将'doc'字符串传递给'ParseJSONValue()',您不需要先将其转换为UTF-8字节数组。 –

1

您正在使用BytesOf(),它使用OS默认的Ansi编码将UnicodeString转换为字节数组。 TJSONObject::Parse()更喜欢而不是UTF-8。它寻找一个UTF-8 BOM,如果没有找到,那么它不会对字节的编码作任何假设,它只会将它们视为8位字符。这在处理非ASCII字符时不起作用,您需要改用UTF-8。要将UnicodeString转换为UTF-8编码的字节数组,你可以使用TEncoding::UTF8::GetBytes(),但你必须在前面加上手动将UTF-8 BOM数组:

UnicodeString doc = L"{\"alias\":\"Test ЮРИСЛАВ\"}"; 
ShowMessage(doc); 

TBytes bytes; 
bytes.Length = 3 + TEncoding::UTF8::GetByteCount(doc); 
bytes[0] = 0xEF; 
bytes[1] = 0xBB; 
bytes[2] = 0xBF; 
TEncoding::UTF8::GetBytes(doc, 1, doc.Length(), bytes, 3); 

TJSONObject* jo = new TJSONObject(); 
jo->Parse(bytes, 0); 
ShowMessage(jo->ToString()); 
//... 
delete jo; 

话虽这么说,你应该直接使用静态TJSONObject::ParseJSONValue()方法而不是TJSONValue::Parse()ParseJSONValue()甚至有一个接受UnicodeString作为输入,将在内部转换为UTF-8编码的字节数组你过载:

UnicodeString doc = L"{\"alias\":\"Test ЮРИСЛАВ\"}"; 
ShowMessage(doc); 
TJSONObject* jo = (TJSONObject*) TJSONObject::ParseJSONValue(doc); 
ShowMessage(jo->ToString()); 
//... 
delete jo; 

但是,如果你确实需要在自己的字节数组通过,其他的ParseJSONValue()重载允许您指定字节数组是否是UTF-8编码或不(它假定默认为UTF-8),所以你并不需要一个BOM:

UnicodeString doc = L"{\"alias\":\"Test ЮРИСЛАВ\"}"; 
ShowMessage(doc); 
TJSONObject* jo = (TJSONObject*) TJSONObject::ParseJSONValue(TEncoding::UTF8::GetBytes(doc), 0, true); 
ShowMessage(jo->ToString()); 
//... 
delete jo;