标签: utf-16

C++ 11中的Unicode

我一直在读一些关于Unicode的主题 - 特别是UTF-8 - (非)支持C++ 11,我希望Stack Overflow上的大师可以向我保证我的理解是正确的,或指出我在哪里误解或错过了某些情况.

简短摘要

首先,好的:您可以在源代码中定义UTF-8,UTF-16和UCS-4文字.此外,<locale>标头包含几个std::codecvt可以在UTF-8,UTF-16,UCS-4和平台多字节编码之间进行转换的实现(虽然API看起来很温和,但不是直截了当).这些codecvt实现可以imbue()在流上进行,以允许您在读取或写入文件(或其他流)时进行转换.

[ 编辑: Cubbi在评论中指出我忽略了提到<codecvt>标题,它提供了std::codecvt不依赖于语言环境的实现.此外,std::wstring_convertwbuffer_convert函数可以使用这些codecvt来直接转换字符串和缓冲区,而不是依赖于流.

C++ 11还包括C99/C11 <uchar.h>标头,其中包含将来自平台多字节编码(可能是或不是UTF-8)的单个字符转换为UCS-2和UCS-4的功能.

但是,这是关于它的程度.虽然你当然可以将UTF-8文本存储在a中std::string,但我无法看到任何对它有用的东西.例如,除了在代码中定义文字之外,您不能将字节数组验证为包含有效的UTF-8,您无法找到长度(即Unicode字符的数量,对于某些"字符"的定义)包含UTF-8 std::string,并且不能std::string以字节为单位以任何方式迭代a .

同样,即使添加C++ 11 std::u16string也不支持UTF-16,但只支持较旧的UCS-2 - 它不支持代理对,只留下BMP.

意见

鉴于UTF-8是在几乎所有Unix派生系统(包括Mac OS X和*Linux)上处理Unicode的标准方式,并且已经在很大程度上成为Web上事实上的标准,现代C++中缺乏支持似乎像一个相当严重的遗漏.即使在Windows上,新std::u16string功能并不真正支持UTF-16 这一事实似乎有些令人遗憾.

*由于在评论中指出,并明确提出在这里的Mac OS使用UTF-8的BSD衍生的部分,而可可使用UTF-16.

问题

如果你设法阅读了所有这些,谢谢!只是几个简单的问题,因为这毕竟是Stack Overflow ...

  • 以上分析是否正确,或者我是否缺少任何其他支持Unicode的设施?

  • 在过去几年中,标准委员会在快速推进C++方面做得非常出色.他们都很聪明,我认为他们很清楚上述缺点.是否有一个众所周知的原因,即Unicode支持在C++中仍然很差?

  • 展望未来,是否有人知道有任何纠正这种情况的建议?快速搜索isocpp.org似乎没有透露任何信息.

编辑:感谢大家的回复.我不得不承认,我发现它们有点令人沮丧 - 看起来现状在不久的将来不太可能改变.如果在认知方面存在共识,似乎完全的Unicode支持太难了,并且任何解决方案必须重新实现大多数ICU才被认为是有用的.

我个人不同意这一点; 我认为可以找到有价值的中间立场.例如,对于UTF-8和UTF-16的验证和归一化算法是由Unicode财团以及指定的,并且可以通过标准库中,比方说自由函数,一个被提供std::unicode的命名空间.仅这些对于需要与期望Unicode输入的库接口的C++程序来说是一个很大的帮助.但基于下面的答案(微笑,必须说,带着一丝苦涩),似乎Puppy关于这种有限功能的提议并不受欢迎.

c++ unicode utf-8 utf-16 c++11

57
推荐指数
1
解决办法
4177
查看次数

Java Unicode字符串长度

我正在努力获取unicode字符串的数量,并尝试了各种选项.看起来像一个小问题,但在很大程度上受到了打击.

在这里,我试图获得字符串str1的长度.我得到它6.但实际上它是3.将光标移动到字符串"குமார்"也显示为3个字符.

基本上我想测量长度并打印每个角色.喜欢"கு","மா","ர்".

 public class one {
    public static void main(String[] args) {
            String str1 = new String("??????");
            System.out.print(str1.length());
    }
}
Run Code Online (Sandbox Code Playgroud)

PS:这是泰米尔语.

java string utf-8 utf-16 unicode-string

55
推荐指数
3
解决办法
8610
查看次数

已弃用标头<codecvt>替换

一点前景:我的任务需要将UTF-8 XML文件转换为UTF-16(当然还有正确的标题).所以我搜索了将UTF-8转换为UTF-16的常用方法,并发现应该使用来自的模板<codecvt>.

但现在当它被弃用时,我想知道执行相同任务的新常用方法是什么?

(根本不介意使用Boost,但除此之外我更喜欢尽可能靠近标准库.)

c++ utf-8 utf-16 codecvt c++17

54
推荐指数
4
解决办法
1万
查看次数

什么是Java的String内部代表?修改过的UTF-8?UTF-16?

我在Java的内部表示中搜索了String,但我有两种看起来可靠但不一致的材料.

一个是:

http://www.codeguru.com/cpp/misc/misc/multi-lingualsupport/article.php/c10451

它说:

Java使用UTF-16作为内部文本表示,并支持对字符串序列化进行非标准的UTF-8修改.

另一个是:

http://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8

它说:

Tcl也使用与Java相同的修改后的UTF-8 [25]来表示Unicode数据,但对外部数据使用严格的CESU-8.

修改过的UTF-8?还是UTF-16?哪一个是正确的?Java在内存中使用了多少字节?

请让我知道哪一个是正确的以及它使用了多少字节.

java string encoding utf-8 utf-16

46
推荐指数
3
解决办法
3万
查看次数

将XML插入SQL Server时如何解决"无法切换编码"错误

我正在尝试插入XML列(SQL SERVER 2008 R2),但服务器抱怨:

System.Data.SqlClient.SqlException(0x80131904):
XML解析:第1行,第39个字符,无法切换编码

我发现XML列必须是UTF-16才能使插入成功.

我正在使用的代码是:

 XmlSerializer serializer = new XmlSerializer(typeof(MyMessage));
 StringWriter str = new StringWriter();
 serializer.Serialize(str, message);
 string messageToLog = str.ToString();
Run Code Online (Sandbox Code Playgroud)

如何将对象序列化为UTF-8字符串?

编辑:好的,抱歉混淆 - 字符串需要是UTF-8.你是对的 - 默认情况下它是UTF-16,如果我尝试以UTF-8插入它就会通过.所以问题是如何序列化为UTF-8.

这会在尝试插入SQL Server时导致错误:

    <?xml version="1.0" encoding="utf-16"?>
    <MyMessage>Teno</MyMessage>
Run Code Online (Sandbox Code Playgroud)

这不是:

    <?xml version="1.0" encoding="utf-8"?>
    <MyMessage>Teno</MyMessage>
Run Code Online (Sandbox Code Playgroud)

更新

我想出当SQL Server 2008的Xml列类型需要utf-8时,以及当encoding你尝试插入xml规范的属性中的utf-16时:

如果要添加utf-8,请将参数添加到SQL命令,如下所示:

 sqlcmd.Parameters.Add("ParamName", SqlDbType.VarChar).Value = xmlValueToAdd;
Run Code Online (Sandbox Code Playgroud)

如果您尝试encoding=utf-16在上一行中添加xmlValueToAdd,则会在插入中产生错误.此外,VarChar意味着国家字符不被识别(它们变成问号).

要将utf-16添加到db,请使用SqlDbType.NVarCharSqlDbType.Xml在前面的示例中,或者根本不指定type:

 sqlcmd.Parameters.Add(new SqlParameter("ParamName", xmlValueToAdd));
Run Code Online (Sandbox Code Playgroud)

.net xml sql-server utf-8 utf-16

43
推荐指数
6
解决办法
7万
查看次数

BMP之外的JavaScript字符串

BMP是基本的多语言平面

根据JavaScript:好的部分:

JavaScript是在16位字符集的时候构建的,因此JavaScript中的所有字符都是16位宽.

这让我相信JavaScript使用UCS-2(不是UTF-16!)并且只能处理U + FFFF以前的字符.

进一步调查证实了这一点:

> String.fromCharCode(0x20001);
Run Code Online (Sandbox Code Playgroud)

fromCharCode返回Unicode字符时,该方法似乎只使用最低16位.试图获得U + 20001(CJK统一表意文字20001)而不是返回U + 0001.

问题:是否可以在JavaScript中处理后BMP字符?


2011-07-31:来自Unicode支持Shootout的 12个幻灯片:好的,坏的,以及(大部分)Ugly很好地解决了与此相关的问题:

javascript unicode utf-16 surrogate-pairs astral-plane

38
推荐指数
1
解决办法
1万
查看次数

ISO/IEC在sizeof(char)中混淆不同的字符集编码,如UTF-16

假设程序在具有UTF-16编码字符集的系统上运行.所以根据C++编程语言 - 第4页,第150页:

char可以保存机器字符集的字符.

→我认为char变量的大小是2字节.

但根据ISO/IEC 14882:2014:

sizeof(char),sizeof(signed char)并且sizeof(unsigned char)是1".

或者C++编程语言 - 第4页,第149页:

"[...],所以根据定义,char的大小是1"

→固定尺寸为1.

问题:上述这些语句之间是否存在冲突,或者sizeof(char) = 1只是默认(定义)值,并且实现定义取决于每个系统?

c++ sizeof utf-16 language-lawyer

37
推荐指数
5
解决办法
1542
查看次数

手动将unicode代码点转换为UTF-8和UTF-16

我有一个大学编程考试,一个部分是关于unicode.

我已经检查了所有的答案,我的讲师没用,所以没有帮助,所以这是你们可能提供帮助的最后手段.

问题将是这样的:

字符串'mЖ丽'具有这些unicode代码点U+006D,U+0416并且 U+4E3D使用十六进制编写的答案,手动将字符串编码为UTF-8和UTF-16.

任何帮助都将非常感激,因为我试图让我的头脑.

unicode utf-8 utf-16

36
推荐指数
2
解决办法
4万
查看次数

Vim:输入带有8位十六进制代码的Unicode字符

如何输入Unicode字符, without copying it to the clipboard and pasting it?

Things I know:

  • The command ga角色上的命令 gives me hex:0001d4ed.
  • 我可以将它复制到剪贴板上并通过它粘贴"+p.
  • 我知道如何输入具有4位十六进制代码的Unicode值:
    <C-v>u例如<C-v>u03b1给出?字符.

unicode vim utf-16 utf

35
推荐指数
3
解决办法
1万
查看次数

Java中的字节和字符转换

如果我将一个角色转换为byte然后再回到char那个角色,那个角色会神秘地消失并成为别的东西.这怎么可能?

这是代码:

char a = 'È';       // line 1       
byte b = (byte)a;   // line 2       
char c = (char)b;   // line 3
System.out.println((char)c + " " + (int)c);
Run Code Online (Sandbox Code Playgroud)

一直到第2行一切都很好:

  • 在第1行,我可以在控制台中打印"a",它会显示"È".

  • 在第2行,我可以在控制台中打印"b",它会显示-56,即200,因为字节已签名.200是"È".所以它仍然很好.

但第3行有什么不对?"c"成为别的东西,程序打印出来? 65480.这是完全不同的东西.

我应该在第3行写什么才能得到正确的结果?

java unicode encoding utf-16

34
推荐指数
1
解决办法
12万
查看次数