我不知道如何解决:
试想一下,我们有4名网站:
- 答:UTF-8
- B:ISO-8859-1
- C:ASCII
- d:UTF-16
我用C ++编写程序执行以下操作:它下载一个网站,并对其进行解析。 但它必须了解的内容。 我的问题是不是该用ASCII字符做过类似的分析">"
或"<"
。
问题是,该方案应找出网站的文本的所有单词。 一个字是字母数字字符的任意组合。 然后我把这些话给服务器。 数据库和网络的前端使用的是UTF-8。 所以我的问题是:
- 我怎么能转换“任何”(或最常用)的字符编码成UTF-8?
- 我怎样才能在C ++ UTF-8字符串的工作? 我认为
wchar_t
不起作用,因为它是2个字节长。 码点的UTF-8是多达4个字节长... - 是否有类似的功能
isspace()
isalnum()
strlen()
tolower()
这样的UTF-8字符串?
请注意:我没有做任何输出(如std::cout
在C)++。 只是过滤掉字,并将其发送到服务器。
我知道UTF8-CPP,但它没有is*()
函数。 当我读,它不会转换其他字符编码成UTF-8。 只有从UTF-*为UTF-8。
编辑:我忘了说,该方案具有可移植:在Windows,Linux,...
我怎么能转换“任何”(或最常用)的字符编码成UTF-8?
ICU (Unicode的国际组件)是这里的解决方案。 人们普遍认为是在支持Unicode的最后发言权。 即使Boost.Locale和Boost.Regex使用它时,它涉及到Unicode。 见我的多莉西顿的回答评论,为什么我建议直接用ICU,而不是包装(如升压)。
您创建一个给定的编码转换器...
#include <ucnv.h>
UConverter * converter;
UErrorCode err = U_ZERO_ERROR;
converter = ucnv_open( "8859-1", &err );
if ( U_SUCCESS( error ) )
{
// ...
ucnv_close( converter );
}
...然后使用的UnicodeString类作为appripriate。
我认为wchar_t的不起作用,因为它是2个字节长。
的大小wchar_t
是实现定义的。 AFAICR,视窗是2字节(UCS-2 / UTF-16,这取决于Windows版本),Linux是4字节(UTF-32)。 在任何情况下,由于标准没有定义的Unicode语义wchar_t
,使用它是不可移植的猜测。 不用猜,使用ICU。
有没有像isspace为函数(),字符isalnum(),strlen的(),tolower的()这样的UTF-8字符串?
不符合他们的UTF-8编码,但你不使用内部反正。 UTF-8是良好的外部表示,但在内部UTF-16或UTF-32是更好的选择。 上述功能确实存在Unicode代码点(即,UChar32); REF。 uchar.h 。
请注意:我不使用C做任何输出(比如std ::法院)++。 只是过滤掉字,并将其发送到服务器。
检查的BreakIterator 。
编辑:我忘了说,该方案具有可移植:在Windows,Linux,...
如果我没有说,它已经, 确实使用ICU,并保存自己吨的麻烦。 即使乍一看似乎有点重量级的,它是最好的实现在那里,这是极为便携(使用它在Windows,Linux和AIX我自己),你会在项目中一次又一次又一次用它来来,所以投资在学习它的API不浪费时间。
不知道这是否会给你你正在寻找的一切,但它可能会有点帮助。 您是否尝试过寻找:
1)Boost.Locale库? Boost.Locale在升压1.48(2011年11月15日),使其更容易从转换并为UTF8 / 16发布
下面是从文档一些方便的例子:
string utf8_string = to_utf<char>(latin1_string,"Latin1");
wstring wide_string = to_utf<wchar_t>(latin1_string,"Latin1");
string latin1_string = from_utf(wide_string,"Latin1");
string utf8_string2 = utf_to_utf<char>(wide_string);
2)或在转换是的C ++ 11部分?
#include <codecvt>
#include <locale>
#include <string>
#include <cassert>
int main() {
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
std::string utf8 = convert.to_bytes(0x5e9);
assert(utf8.length() == 2);
assert(utf8[0] == '\xD7');
assert(utf8[1] == '\xA9');
}
我怎样才能在C ++ UTF-8字符串的工作? 我认为wchar_t的不起作用,因为它是2个字节长。 码点的UTF-8是多达4个字节长...
这是很容易,有一个名为项目tinyutf8 ,这是一个简易替换 std::string
/ std::wstring
。
然后,用户可以上优雅码点操作,同时其表示在总是被编码char
秒。
我怎么能转换“任何”(或最常用)的字符编码成UTF-8?
你可能想看看std::codecvt_utf8
和simlilar模板从<codecvt>
(C ++ 11)。
UTF-8是使用用于利用所述第8位的非ASCII(7位代码)多个字节的编码。 因此,你不会找到'\'
, '/'
多字节序列内。 和isdigit
作品(虽然不是阿拉伯语和其他数字)。
这是ASCII的一个超集,可以容纳所有Unicode字符,所以肯定有字符和字符串使用。
检查的HTTP标头(不区分大小写); 他们是在ISO 8859,并先于一个空行,然后HTML内容。
Content-Type: text/html; charset=UTF-8
如果不出现,也有可能是
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="UTF-8"> <!-- HTML5 -->
ISO-8859-1是拉丁文1,你可能做的更好从Windows 1252转换,在Windows Latin-1的扩展使用0x80的 - 为0xBF对于一些特殊的字符,如逗号报价和这样。 虽然指定了ISO-8859即使在MacOS浏览器会理解这些。
转换库:通过@syam提到alread。
转变
让我们不要考虑UTF-16。 一个可以读取头,并开始直到该字符集的单字节字符元声明。
从单字节编码为UTF-8的转化可以通过表格发生。 例如使用Java生成:一个const char* table[]
索引由炭。
table[157] = "\xEF\xBF\xBD";
public static void main(String[] args) {
final String SOURCE_ENCODING = "windows-1252";
byte[] sourceBytes = new byte[1];
System.out.println(" const char* table[] = {");
for (int c = 0; c < 256; ++c) {
String comment = "";
System.out.printf(" /* %3d */ \"", c);
if (32 <= c && c < 127) {
// Pure ASCII
if (c == '\"' || c == '\\')
System.out.print("\\");
System.out.print((char)c);
} else {
if (c == 0) {
comment = " // Unusable";
}
sourceBytes[0] = (byte)c;
try {
byte[] targetBytes = new String(sourceBytes, SOURCE_ENCODING).getBytes("UTF-8");
for (int j = 0; j < targetBytes.length; ++j) {
int b = targetBytes[j] & 0xFF;
System.out.printf("\\x%02X", b);
}
} catch (UnsupportedEncodingException ex) {
comment = " // " + ex.getMessage().replaceAll("\\s+", " "); // No newlines.
}
}
System.out.print("\"");
if (c < 255) {
System.out.print(",");
}
System.out.println();
}
System.out.println(" };");
}