首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

UTF-8 字串處理核心技術:單字拆分與字元計數的原理與 C++ 實作

     編輯:C++ 入門

字元編碼基礎回顧

ASCII:單位元組的起點

ASCII 使用 7 位元編碼 128 個符號(0x00–0x7F),最高位固定為 0。適用於英文環境,但無法表示中文、日文等非拉丁字母。

Unicode:統一碼表

Unicode 為每個字符分配唯一碼位(Code Point),目前超過 100 萬字符。但它僅定義「碼位」,未規定儲存方式(即不指定如何將整數序列轉為位元組流)。

UTF-8:變長編碼的實戰標準

UTF-8 是 Unicode 的一種實作,特點是向後相容 ASCII且無位元組序問題。編碼規則:

  • 1 位元組:0xxxxxxx(ASCII 字符)
  • n 位元組 (n>1):首位元組前 n 位為 1、第 n+1 位為 0(如 110xxxxx、1110xxxx),後續位元組均為 10xxxxxx。

實際可用資料位最多 31 位,足以覆蓋所有 Unicode 碼位。

UTF-8 字串拆分為單字集合

利用首位元組的前導位數即可判斷字元長度,無需解碼完整碼位:

size_t utf8_to_charset(const std::string &input, std::set<std::string> &output) {
    std::string ch;
    for (size_t i = 0, len = 0; i != input.length(); i += len) {
        unsigned char byte = static_cast<unsigned char>(input[i]);
        if (byte >= 0xFC) len = 6;
        else if (byte >= 0xF8) len = 5;
        else if (byte >= 0xF0) len = 4;
        else if (byte >= 0xE0) len = 3;
        else if (byte >= 0xC0) len = 2;
        else len = 1;
        ch = input.substr(i, len);
        output.insert(ch); // 若需保留順序,改用 vector
    }
    return output.size();
}

關鍵點解析

  1. unsigned char 強制轉換避免負數擴展干擾位運算。
  2. 依序判斷 0xFC (11111100) 至 0xC0 (11000000),對應 6~2 位元組字元。
  3. substr(i, len) 直接切出原始位元組序列,保留編碼原貌。

計算 UTF-8 字串的字元數(非位元組數)

size_t get_utf8_length(const std::string &input) {
    size_t length = 0;
    for (size_t i = 0, len = 0; i != input.length(); i += len) {
        unsigned char byte = input[i];
        if (byte >= 0xFC) len = 6;
        else if (byte >= 0xF8) len = 5;
        else if (byte >= 0xF0) len = 4;
        else if (byte >= 0xE0) len = 3;
        else if (byte >= 0xC0) len = 2;
        else len = 1;
        ++length;
    }
    return length;
}

同樣邏輯,僅累加字元計數器。注意:此函數假設輸入為合法 UTF-8,實際專案建議加入錯誤碼位檢測(如過長序列、代理區碼位等)。

進階應用與效能考量

  • 避免重複解碼:若需同時取得字元邊界與碼位值,可結合 char32_t 單次掃描完成。
  • SIMD 加速:現代 CPU 可用 SSE/AVX 並行判斷首位元組類別,大幅提升長字串處理速度。
  • 標準庫替代:C++20 <charconv>、ICU 庫或 Boost.Nowide 提供更健壯的 Unicode 支援。

常見坑點提醒

  1. 將 char 直接當有號數比較(如 if (c > 0x80)),導致中文字元誤判。
  2. 假設中文固定 3 位元組——實際 UTF-8 中漢字多為 3 位元組,但生僻字、Emoji 可能為 4 位元組。
  3. 在字元邊界之外截斷字串(如 substr(0, 10)),產生無效 UTF-8 序列。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved