ASCII 使用 7 位元編碼 128 個符號(0x00–0x7F),最高位固定為 0。適用於英文環境,但無法表示中文、日文等非拉丁字母。
Unicode 為每個字符分配唯一碼位(Code Point),目前超過 100 萬字符。但它僅定義「碼位」,未規定儲存方式(即不指定如何將整數序列轉為位元組流)。
UTF-8 是 Unicode 的一種實作,特點是向後相容 ASCII且無位元組序問題。編碼規則:
0xxxxxxx(ASCII 字符)110xxxxx、1110xxxx),後續位元組均為 10xxxxxx。實際可用資料位最多 31 位,足以覆蓋所有 Unicode 碼位。
利用首位元組的前導位數即可判斷字元長度,無需解碼完整碼位:
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();
}
unsigned char 強制轉換避免負數擴展干擾位運算。0xFC (11111100) 至 0xC0 (11000000),對應 6~2 位元組字元。substr(i, len) 直接切出原始位元組序列,保留編碼原貌。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 單次掃描完成。<charconv>、ICU 庫或 Boost.Nowide 提供更健壯的 Unicode 支援。char 直接當有號數比較(如 if (c > 0x80)),導致中文字元誤判。substr(0, 10)),產生無效 UTF-8 序列。