我正在寻找有关unicode感知std :: string库替换的建议。我有一堆使用std :: string,它的迭代器等的代码,并且现在想支持unicode字符串(首选免费或开源实现,正则表达式功能会很棒!)。
我现在还不确定是否需要完全重写,或者我是否可以放弃支持所有std :: string接口的新字符串库。 unicode世界似乎非常复杂,我只是想在我的应用程序中启用它而不必学习它的每一个方面。
btw当索引运算符必须将引用传递回1,2,3或4结构时,它如何工作,理论上它可以改为1,2,3或4字节结构。如果传递更大或更小的值,内部数据表示的来回移位是否会原位发生?
答案 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可以在没有多字节的情况下使用:)
希望这有帮助!