Unicode std :: string类替换

时间:2011-05-17 08:22:08

标签: c++ string unicode locale

我正在寻找有关unicode感知std :: string库替换的建议。我有一堆使用std :: string,它的迭代器等的代码,并且现在想支持unicode字符串(首选免费或开源实现,正则表达式功能会很棒!)。

我现在还不确定是否需要完全重写,或者我是否可以放弃支持所有std :: string接口的新字符串库。 unicode世界似乎非常复杂,我只是想在我的应用程序中启用它而不必学习它的每一个方面。

btw当索引运算符必须将引用传递回1,2,3或4结构时,它如何工作,理论上它可以改为1,2,3或4字节结构。如果传递更大或更小的值,内部数据表示的来回移位是否会原位发生?

5 个答案:

答案 0 :(得分:10)

如果确定std :: string包含的内容,则不需要完全重写。例如,您可以假设(并转换输入以确保)您的std :: string包含UTF8编码的字符串(对于那些需要本地化的字符串)。不要忘记std :: string只是原始数据的容器,它与编码无关(即使在C ++ 0x中,它只是一种可能性,而不是一种要求)。

然后,当您将文本传递给需要不同编码的其他库时,您可以使用像UTF8CPP这样的库来转换为所需的编码(但大多数情况下,此类库会自行完成)。

这样简单。在您的代码中使用标准std :: string的UTF8,允许将unicode字符串传递给其他所有内容(如果需要,可以进行转换)。

在boost社区邮件列表中已经有很多关于此的讨论。也许阅读它(如果你有足够的时间......)可以帮助你理解其他可能的解决方案。

答案 1 :(得分:7)

根据您的需要,使用std :: wstring或更大,更复杂(但事实上标准)的ICU:http://site.icu-project.org/

答案 2 :(得分:6)

你需要什么unicode编码?如果utf-8没问题,你可以查看Glib::ustring

  

Glib :: ustring有很多相同之处   interface as std :: string,但包含   Unicode字符编码为UTF-8。

答案 3 :(得分:1)

要求“像std :: string这样的类型,但对于Unicode”就像要求“类似无符号的类型,但对于素数”。 std :: string完全能够以许多编码存储Unicode - 最常用的是UTF-8。

您需要替换的是迭代器,而不是存储类型。迭代器应迭代字符串的代码点而不是字节。也就是说,++i应该提前一个代码点,*i应该返回一个代码点(通过uint32_t)而不是char

答案 4 :(得分:0)

我已经编写了自己的C++ UTF-8 library,这是[root@spark2 ~]# dse spark Welcome to ____ __ / __/__ ___ _____/ /__ _\ \/ _ \/ _ `/ __/ '_/ /___/ .__/\_,_/_/ /_/\_\ version 1.4.1 /_/ Using Scala version 2.10.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45) Type in expressions to have them evaluated. Type :help for more information. Creating SparkContext... Initializing SparkContext with MASTER: spark://1.2.3.4:7077 Created spark context.. Spark context available as sc. Hive context available as hc. CassandraSQLContext available as csc. scala> val results = csc.sql("select h.id, h.program,s.flux from has.header h join has.s1d_flux s on h.id=s.id").cache(); results: org.apache.spark.sql.DataFrame = [id: uuid, program: string, flux: string] scala> results.take(1).foreach(println); [Stage 0:> (0 + 11) / 11][Stage 1:> (0 + 1) / 2620]WARN 2015-11-21 12:01:26 org.apache.spark.scheduler.TaskSetManager: Lost task 3.0 in stage 0.0 (TID 6, 161.72.45.76): scala.MatchError: UUIDType (of class org.apache.spark.sql.cassandra.types.UUIDType$) at org.apache.spark.sql.execution.SparkSqlSerializer2$$anonfun$createSerializationFunction$1.apply(SparkSqlSerializer2.scala:232) at org.apache.spark.sql.execution.SparkSqlSerializer2$$anonfun$createSerializationFunction$1.apply(SparkSqlSerializer2.scala:227) at org.apache.spark.sql.execution.Serializer2SerializationStream.writeKey(SparkSqlSerializer2.scala:65) at org.apache.spark.storage.DiskBlockObjectWriter.write(BlockObjectWriter.scala:206) at org.apache.spark.util.collection.WritablePartitionedIterator$$anon$3.writeNext(WritablePartitionedPairCollection.scala:104) at org.apache.spark.util.collection.ExternalSorter.spillToPartitionFiles(ExternalSorter.scala:375) at org.apache.spark.util.collection.ExternalSorter.insertAll(ExternalSorter.scala:208) at org.apache.spark.shuffle.sort.SortShuffleWriter.write(SortShuffleWriter.scala:62) at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:70) at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:41) at org.apache.spark.scheduler.Task.run(Task.scala:70) at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:213) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) [Stage 0:> / std::wstring的替代品。向用户显示的数据类型为string,但内部宽字符全部打包到utf8 char32_t中。

整个事情非常快,并且在许多ascii代码点中很少有unicode代码点,因此性能最佳。从字节索引开始,std :: string中已知的所有操作都可用于此类(子字符串char除外),操作于代码点索引

作为防御性编程的奖励,整个ANSI范围0-255可以在没有多字节的情况下使用:)

希望这有帮助!