获取uft8, utf16编码字符数量

#include <iostream>


// UTF-8 编码标准
// 
// 1字节 U+0000000 - U+0000007F 0xxxxxxx
// 2字节 U+0000080 - U+000007FF 110xxxxx 10xxxxxx
// 3字节 U+0000800 - U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
// 4字节 U+0010000 - U+001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
// 5字节 U+0200000 - U+03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
// 6字节 U+4000000 - U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

// UTF16 编码标准
// 
// 基本多语言平面(U+0000 - U+FFFF)
// 
// 辅助平面(U+10000 - U+10FFFF)
// 1.码位减去 0x10000,得到20位的代理值(0x00 - 0xFFFFF)
// 2.高10位(范围0 - 0x3FF)加 0xD800 得到高位代理(0xD800 - 0xDBFF)
// 3.低10位(范围0 - 0x3FF)加 0xDC00 得到低位代理(0xDC00 - 0xDFFF)

int GetUtf8Count(const std::string& str);
int GetUtf16Count(const std::wstring& str);
int GetUtf8Count(const void* data_ptr, size_t size = -1);
int GetUtf16Count(const void* data_ptr, size_t size = -1);

int main()
{
    std::wstring strUtf16 = L"我是地球🌍";
    std::cout << GetUtf16Count(strUtf16) << std::endl;
    std::string strUtf8 = u8"我是地球🌍";
    std::cout << GetUtf8Count(strUtf8) << std::endl;

    return 0;
}

int GetUtf8Count(const std::string& str)
{
    return GetUtf8Count(str.c_str(), str.size());
}

int GetUtf16Count(const std::wstring& str)
{
    return GetUtf16Count(str.c_str(), str.size() * sizeof(wchar_t));
}

int GetUtf8Count(const void* data_ptr, size_t size/* = -1*/)
{
    const uint8_t* ch_data_ptr = (const uint8_t*)data_ptr;
    std::wstring text_out_utf16;
    std::string text_out_utf8;
    uint32_t cp32 = 0;
    int32_t byte_count = 0;
    int32_t ch_count = 0;
    bool result_flag = true;

    while ((0 != *ch_data_ptr) && (0 != size))
    {
        uint8_t ch = *ch_data_ptr;

        if (ch < 0x7F)
        {
            cp32 = ch;
            ch_count++;
        }
        else
        {
            if (0 == byte_count)
            {
                cp32 = 0;
                if (ch >= 0xC0)
                {
                    if (ch >= 0xC0 && ch <= 0xDF)
                    {
                        byte_count = 2;
                        cp32 = ch & 0x1F;
                    }
                    else if (ch >= 0xE0 && ch <= 0xEF)
                    {
                        byte_count = 3;
                        cp32 = ch & 0x0F;
                    }
                    else if (ch >= 0xF0 && ch <= 0xF7)
                    {
                        byte_count = 4;
                        cp32 = ch & 0x07;
                    }
                    else if (ch >= 0xF8 && ch <= 0xFB)
                    {
                        byte_count = 5;
                        cp32 = ch & 0x03;
                    }
                    else if (ch >= 0xFC && ch <= 0xFD)
                    {
                        byte_count = 6;
                        cp32 = ch & 0x01;
                    }

                    if (0 == byte_count)
                    {
                        result_flag = false;
                        break;
                    }

                    byte_count--;
                }
                else
                {
                    result_flag = false;
                    break;
                }
            }
            else
            {
                if (0x80 != (ch & 0xC0))
                {
                    result_flag = false;
                    break;
                }

                cp32 = cp32 << 6;
                cp32 |= ch & 0x3F;

                byte_count--;

                if ((0 == byte_count) && (0xFEFF != cp32))
                {
                    ch_count++;
                }
            }
        }

        ch_data_ptr++;

        if (-1 != size)
        {
            size--;
        }
    }

    if (!result_flag)
    {
        return -1;
    }

    return ch_count;
}

int32_t GetUtf16Count(const void* data_ptr, size_t size/* = -1*/)
{
    const uint16_t* ch_data_ptr = (const uint16_t*)data_ptr;
    uint32_t cp32 = 0;
    uint16_t cp32_high = 0;
    uint16_t cp32_low = 0;
    uint16_t cp16 = 0;
    int32_t byte_count = 0;
    int32_t ch_count = 0;
    bool flag_big_endian = false;
    bool flag_little_endian = false;
    bool result_flag = true;

    if (-1 != size)
    {
        if ((size < 2) || (0 != (size % 2)))
        {
            return -1;
        }
    }

    while ((0 != *ch_data_ptr) && (0 != size))
    {
        cp16 = *ch_data_ptr;

        if (0xFFFE == cp16 || 0xFEFF == cp16)
        {
            if (0 == byte_count)
            {
                if (0xFFFE == cp16)
                {
                    flag_big_endian = true;
                }

                if (0xFEFF == cp16)
                {
                    flag_little_endian = true;
                }
            }
            else
            {
                result_flag = false;
                break;
            }

            if (flag_big_endian && flag_little_endian)
            {
                result_flag = false;
                break;
            }

            ch_data_ptr++;

            if (-1 != size)
            {
                size -= 2;
            }

            continue;
        }

        if (flag_big_endian)
        {
            cp16 = ((cp16 >> 8) | (cp16 << 8));
        }

        if (!(cp16 >= 0xD800 && cp16 <= 0xDFFF))
        {
            if (cp32_high > 0)
            {
                result_flag = false;
                break;
            }

            cp32 = cp16;
            ch_count++;
        }
        else
        {
            if (0 == byte_count)
            {
                if (cp16 >= 0xD800 && cp16 <= 0xDBFF)
                {
                    cp32_high = (cp16 - 0xD800);
                    byte_count = 1;
                }
                else
                {
                    result_flag = false;
                    break;
                }
            }
            else
            {
                if (1 == byte_count)
                {
                    if ((cp16 >= 0xDC00) && (cp16 <= 0xDFFF))
                    {
                        cp32_low = (cp16 - 0xDC00);
                        cp32 = 0x10000 + ((uint32_t)cp32_high << 10 | cp32_low);
                        cp32_low = 0;
                        cp32_high = 0;
                    }
                    else
                    {
                        result_flag = false;
                        break;
                    }
                }

                byte_count--;

                if (0 == byte_count)
                {
                    ch_count++;
                }
            }
        }

        ch_data_ptr++;

        if (-1 != size)
        {
            size -= 2;
        }
    }

    if (!result_flag)
    {
        return -1;
    }

    return ch_count;
}

内容概要:本文详细介绍了如何使用STM32微控制器精确控制步进电机,涵盖了从原理到代码实现的全过程。首先,解释了步进电机的工作原理,包括定子、转子的构造及其通过脉冲信号控制转动的方式。接着,介绍了STM32的基本原理及其通过GPIO端口输出控制信号,配合驱动器芯片放大信号以驱动电机运转的方法。文中还详细描述了硬件搭建步骤,包括所需硬件的选择与连接方法。随后提供了基础控制代码示例,演示了如何通过定义控制引脚、编写延时函数和控制电机转动函数来实现步进电机的基本控制。最后,探讨了进阶优化技术,如定时器中断控制、S形或梯形加减速曲线、微步控制及DMA传输等,以提升电机运行的平稳性和精度。 适合人群:具有嵌入式系统基础知识,特别是对STM32和步进电机有一定了解的研发人员和技术爱好者。 使用场景及目标:①学习步进电机与STM32的工作原理及二者结合的具体实现方法;②掌握硬件连接技巧,确保各组件间正确通信;③理解并实践基础控制代码,实现步进电机的基本控制;④通过进阶优化技术的应用,提高电机控制性能,实现更精细和平稳的运动控制。 阅读建议:本文不仅提供了详细的理论讲解,还附带了完整的代码示例,建议读者在学习过程中动手实践,结合实际硬件进行调试,以便更好地理解和掌握步进电机的控制原理和技术细节。同时,对于进阶优化部分,可根据自身需求选择性学习,逐步提升对复杂控制系统的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值