如何从 UTF-8 字符串的每个字符中获取 UNICODE 代码?
Posted
技术标签:
【中文标题】如何从 UTF-8 字符串的每个字符中获取 UNICODE 代码?【英文标题】:How to get the UNICODE code from each character of a UTF-8 string? 【发布时间】:2014-02-11 19:51:01 【问题描述】:使用 C++11,我如何从 UTF-8 编码的std::string
将文本中每个字符的 Unicode 值转换为uint32_t
?
类似:
void f(const std::string &utf8_str)
for(???)
uint32_t code = ???;
/* Do my stuff with the code... */
假设主机系统语言环境是 UTF-8 有帮助吗? C++11 为这项任务提供了哪些标准库工具?
【问题讨论】:
【参考方案1】:您可以简单地将字符串转换为 UTF-32 编码的字符串,使用提供的转换方面和来自<locale>
的std::wstring_convert
:
#include <codecvt>
#include <locale>
#include <string>
void foo(std::string const & utf8str)
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv;
std::u32string utf32str = conv.from_bytes(utf8str);
for (char32_t u : utf32str) /* ... */
【讨论】:
你知道如何获取系统原生编码的codecvt,而不是UTF-8吗? @lvella:您可以使用mbrtoc32
将系统的窄编码转换为UTF32。链接页面底部的表格显示了所有可用的组合。 (不过,I'm not sure 如果 <cuchar>
已被广泛实施。)
@lvella 系统的本机编码而不是 UTF-8?如果您的意思是 GB18030(另一种 8 位 Unicode 格式),那么您可以使用 codecvt_byname 或使用 use_facet 将其从语言环境中提取出来。 This example 展示了如何使用它构建 wstring_convert。
...您可能需要调用std::setlocale(LC_CTYPE, "")
或其他适合相关流的方式来获取实际的系统区域设置...
mbrtoc32
是一个很奇怪的东西……它记录了负返回值,但返回了一个 size_t
,它是无符号的。【参考方案2】:
使用来自http://utfcpp.sourceforge.net/ 的<utf8.h>
你可以编码:
static inline void fix_utf8_string(std::string& str)
std::string temp;
utf8::replace_invalid(str.begin(), str.end(), back_inserter(temp));
str = temp;
static inline bool valid_utf8_cstr(const char*s)
if (!s) return false;
const char* e = s+strlen(s);
return utf8::is_valid(s,e);
static inline size_t
utf8_length(const char*s)
if (!s) return 0;
const char* e = s+strlen(s);
return utf8::distance(s,e);
// apply a function to every code point, exiting if that function
// gives true and return the number of visited code points
static inline size_t
utf8_foreach_if(const char*s,
std::function<bool(uint32_t,size_t)>f)
if (!s) return 0;
size_t ix=0;
const char*pc = s;
while(*pc)
const char*epc
= (pc[1]==0)?(pc+1):(pc[2]==0)
?(pc+2):(pc[3]==0)?(pc+3):(pc+4);
uint32_t c = utf8::next(pc,epc);
if (f(c,ix)) break;
ix++;
;
return ix;
static inline size_t
utf8_foreach_if(const std::string& s,
std::function<bool(uint32_t,size_t)>f)
if (s.empty()) return 0;
size_t ix=0;
const char*pc = s.c_str();
const char*epc = pc + s.size();
while(*pc)
uint32_t c = utf8::next(pc,epc);
if (f(c,ix)) break;
ix++;
;
return ix;
这是从我将在几周或几个月内发布的一些 GPLv3 许可代码中提取的。
【讨论】:
以上是关于如何从 UTF-8 字符串的每个字符中获取 UNICODE 代码?的主要内容,如果未能解决你的问题,请参考以下文章
如何随机从数组中获取随机字符串项,并将字符串单词的每个字符随机放入li标签中
如何在 Ruby 2.1 中获取给定 UTF-8 代码的字符