Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;迭代或将UTF-8字符串拆分为符号数组?_C++_Arrays_Utf 8_Split - Fatal编程技术网

C++ C++;迭代或将UTF-8字符串拆分为符号数组?

C++ C++;迭代或将UTF-8字符串拆分为符号数组?,c++,arrays,utf-8,split,C++,Arrays,Utf 8,Split,搜索与平台和第三方库无关的迭代UTF-8字符串或将其拆分为UTF-8符号数组的方法 请发布一段代码片段 已解决: 试试。如果我理解正确,听起来您想找到每个UTF-8字符的开头。如果是这样,那么解析它们就相当简单了(解释它们是另一回事)。但涉及多少个八位组的定义由以下机构明确定义: 例如,如果lb具有UTF-8字符的第一个八位字节,我认为下面将确定所涉及的八位字节数 unsigned char lb; if (( lb & 0x80 ) == 0 ) // lead b

搜索与平台和第三方库无关的迭代UTF-8字符串或将其拆分为UTF-8符号数组的方法

请发布一段代码片段

已解决:

试试。

如果我理解正确,听起来您想找到每个UTF-8字符的开头。如果是这样,那么解析它们就相当简单了(解释它们是另一回事)。但涉及多少个八位组的定义由以下机构明确定义:

例如,如果
lb
具有UTF-8字符的第一个八位字节,我认为下面将确定所涉及的八位字节数

unsigned char lb;

if (( lb & 0x80 ) == 0 )          // lead bit is zero, must be a single ascii
   printf( "1 octet\n" );
else if (( lb & 0xE0 ) == 0xC0 )  // 110x xxxx
   printf( "2 octets\n" );
else if (( lb & 0xF0 ) == 0xE0 ) // 1110 xxxx
   printf( "3 octets\n" );
else if (( lb & 0xF8 ) == 0xF0 ) // 1111 0xxx
   printf( "4 octets\n" );
else
   printf( "Unrecognized lead byte (%02x)\n", lb );
不过,最终,正如另一篇文章所建议的那样,使用现有库会让您受益匪浅。上面的代码可能会根据八位字节对字符进行分类,但一旦完成,它不会帮助“处理”字符。

即兴:

// Return length of s converted. On success return should equal s.length().
// On error return points to the character where decoding failed.
// Remember to check the success flag since decoding errors could occur at
// the end of the string
int convert(std::vector<int>& u, const std::string& s, bool& success) {
    success = false;
    int cp = 0;
    int runlen = 0;
    for (std::string::const_iterator it = s.begin(), end = s.end(); it != end; ++it) {
        int ch = static_cast<unsigned char>(*it);
        if (runlen > 0) {
            if ((ch & 0xc0 != 0x80) || cp == 0) return it-s.begin();
            cp = (cp << 6) + (ch & 0x3f);
            if (--runlen == 0) {
                u.push_back(cp);
                cp = 0;
            }
        }
        else if (cp == 0) {
            if (ch < 0x80)      { u.push_back(ch); }
            else if (ch > 0xf8) return it-s.begin();
            else if (ch > 0xf0) { cp = ch & 7; runlen = 3; }
            else if (ch > 0xe0) { cp = ch & 0xf; runlen = 2; }
            else if (ch > 0xc0) { cp = ch & 0x1f; runlen = 1; }
            else return it-s.begin(); // stop on error
        }
        else return it-s.begin();
    }
    success = runlen == 0; // verify we are between codepoints
    return s.length();
}
//返回已转换的s的长度。成功返回时应等于s.length()。
//On error返回指向解码失败的字符。
//请记住检查成功标志,因为解码错误可能发生在
//弦外之音
int转换(std::vector&u、const std::string&s、bool&success){
成功=错误;
int cp=0;
int-runlen=0;
对于(std::string::const_迭代器it=s.begin(),end=s.end();it!=end;++it){
int ch=静态施法(*it);
如果(runlen>0){
if((ch&0xc0!=0x80)| | cp==0)返回它-s.begin();
cp=(cp 0xf8)返回它-s.begin();
如果(ch>0xf0){cp=ch&7;runlen=3;}
如果(ch>0xe0){cp=ch&0xf;runlen=2;}
如果(ch>0xc0){cp=ch&0x1f;runlen=1;}
否则返回-s.begin();//出错时停止
}
否则返回-s.begin();
}
success=runlen==0;//验证我们在代码点之间
返回s.length();
}

正是您想要的

使用小型平台独立库解决的问题:

char*str=(char*)text.c_str();//utf-8字符串
char*str_i=str;//字符串迭代器
char*end=str+strlen(str)+1;//结束迭代器
做
{
uint32_t code=utf8::next(str_i,end);//获取utf-8符号的32位代码
如果(代码==0)
继续;
无符号字符[5]符号={0};
utf8::append(code,symbol);//将代码复制到symbol
//…用符号做点什么
}
而(str_i
C++没有任何处理UTF-8编码的标准工具。所以,要么使用单独的库,要么编写自己的库。写自己的是可能的,但有无数的细节。是的,这就是我问这个问题的原因。“第三方库独立方式”+1 ICU是一个跨平台库,根据许可的开源许可证发布。如果OP希望避免依赖第三方库,ICU的源代码是免费的,但包含超过1e+06行代码。它是开源的。您可以尝试从中使用字符串迭代器源代码,而不是所有1e+06行代码。谢谢。endianess对这个函数重要吗?“如果(*it<0x80){u.push_back(*it);}”=>“由于数据类型范围有限,比较总是正确的”从
const char*const'到
char*'的转换无效Ok,我修复了错误。UTF8是严格的字节级,所以endianness不重要。我再说一遍。UTF8是字节级编码。这意味着您按顺序读取每个字节。在IP端口之间或从主存储器到微处理器寄存器的传输顺序并不重要。当这些位重新组合在一起时,它们在所有处理器上的解释方式相同(19==19)。Endianness不是问题。我已经自己找到了这个图书馆。我需要一个密码,不过还是谢谢你。回答得很好!这正是我要找的!谢谢在某些语言中,一个单词包含两个或两个以上的符号,如'哈哈' 在中文里,应该用
vector
来存储单词吗?如果是这样,比较单词似乎需要迭代向量/数组,而且速度相当慢。。。
// Return length of s converted. On success return should equal s.length().
// On error return points to the character where decoding failed.
// Remember to check the success flag since decoding errors could occur at
// the end of the string
int convert(std::vector<int>& u, const std::string& s, bool& success) {
    success = false;
    int cp = 0;
    int runlen = 0;
    for (std::string::const_iterator it = s.begin(), end = s.end(); it != end; ++it) {
        int ch = static_cast<unsigned char>(*it);
        if (runlen > 0) {
            if ((ch & 0xc0 != 0x80) || cp == 0) return it-s.begin();
            cp = (cp << 6) + (ch & 0x3f);
            if (--runlen == 0) {
                u.push_back(cp);
                cp = 0;
            }
        }
        else if (cp == 0) {
            if (ch < 0x80)      { u.push_back(ch); }
            else if (ch > 0xf8) return it-s.begin();
            else if (ch > 0xf0) { cp = ch & 7; runlen = 3; }
            else if (ch > 0xe0) { cp = ch & 0xf; runlen = 2; }
            else if (ch > 0xc0) { cp = ch & 0x1f; runlen = 1; }
            else return it-s.begin(); // stop on error
        }
        else return it-s.begin();
    }
    success = runlen == 0; // verify we are between codepoints
    return s.length();
}
    char* str = (char*)text.c_str();    // utf-8 string
    char* str_i = str;                  // string iterator
    char* end = str+strlen(str)+1;      // end iterator

    do
    {
        uint32_t code = utf8::next(str_i, end); // get 32 bit code of a utf-8 symbol
        if (code == 0)
            continue;

        unsigned char[5] symbol = {0};
        utf8::append(code, symbol); // copy code to symbol

        // ... do something with symbol
    }
    while ( str_i < end );