utf8字符计数不起作用

时间:2014-03-10 20:07:03

标签: c++ unicode utf-8

有人可以解释为什么第一个功能有效,但第二个功能没有?

unsigned int utf8_count(char* in)
{
    unsigned int i = 0, c = 0;
    while (in[i])
    {
        if ((in[i] & 0xc0) != 0x80)
            c++;

        i++;
    }

    return c;
}

unsigned int utf8_count(char* in, unsigned int in_size)
{
    unsigned int i = 0, c = 0;
    while (i < in_size)
    {
        if ((in[i] & 0xc0) != 0x80)
            c++;

        i++;
    }

    return c;
}

我理解(in[i] & 0xc0) != 0x80的作用,但我不明白为什么i < in_size != in[i]

示例字符串:ゴールデンタイムラバー/スキマスイッチ 57个字节,19个字符。

为什么utf8_count(in, 57)会返回57而不是19?

示例字符串的二进制表示形式:

enter image description here

2 个答案:

答案 0 :(得分:2)

您看到的问题是您的示例字符串。

看看ゴールデンタイムラバー/スキマスイッチ 您的示例字节在空字节之前显示18x'00111111'。 根据我的计算,第一个函数应返回18,第二个函数应返回更大的数字。你确定你传递了正确的字符串吗?

我不认为你在图像中显示的字节对应于文本ゴールデンタイムラバー/スキマスイッチ(如果只是因为我没有看到在该字符串的开头重复多次相同的字符。< / p>

答案 1 :(得分:1)

在这里工作得很好.. http://ideone.com/oepQg1

我使用g ++ 4.8.1和MSVC 2013在Windows 8上的两个CodeBlock中测试了它。还在linux上尝试过它.. Works。他们都打印19 ..

所以无论你喂食什么,它都不是你在OP中所拥有的那个字符串..

// UTF8Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <cstring>
#include <clocale>

int strlen_u8(const char* str)
{
    int I = 0, J = 0;

    while (str[I])
    {
        if ((str[I] & 0xC0) != 0x80)
        {
            ++J;
        }
        ++I;
    }
    return J;
}

int strlen_s_u8(const char* str, unsigned int size)
{
    unsigned int I = 0, J = 0;
    while (I < size)
    {
        if ((str[I] & 0xC0) != 0x80)
        {
            ++J;
        }
        ++I;
    }
    return J;
}


#if defined _MSC_VER || defined _WIN32 || defined _WIN64
int _tmain(int argc, _TCHAR* argv[])
#else
int main(int argc, char* argv[])
#endif
{
    #ifdef _MSC_VER
    const char* str = "ゴールデンタイムラバー/スキマスイッチ";
    #else
    const char* str = u8"ゴールデンタイムラバー/スキマスイッチ";
    std::setlocale(LC_ALL, "ja_JP.UTF-8");
    #endif

    std::cout << strlen_u8(str) << "\n";
    std::cout << strlen_s_u8(str, strlen(str)) << "\n"; //can use 57 instead of strlen.
    std::cin.get();
}