#include <iostream>
#include <string>
/*
Function: utf8_length
---------------------
Counts how many Unicode code points exist in a UTF‑8 encoded std::string.
Why this is needed:
-------------------
- std::string::size() returns the number of BYTES.
- UTF‑8 characters may use 1–4 bytes.
- To count actual characters (code points), we must decode UTF‑8 manually.
UTF‑8 encoding rules:
---------------------
1-byte: 0xxxxxxx
2-byte: 110xxxxx 10xxxxxx
3-byte: 1110xxxx 10xxxxxx 10xxxxxx
4-byte: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
size_t utf8_length(const std::string& s) {
size_t length = 0; // number of Unicode code points
size_t i = 0; // index into the byte string
while (i < s.size()) {
unsigned char c = s[i];
// Determine how many bytes this UTF‑8 character uses
if (c < 0x80) {
// 1-byte ASCII character
i += 1;
}
else if ((c >> 5) == 0x6) {
// 110xxxxx → 2-byte character
i += 2;
}
else if ((c >> 4) == 0xE) {
// 1110xxxx → 3-byte character
i += 3;
}
else if ((c >> 3) == 0x1E) {
// 11110xxx → 4-byte character
i += 4;
}
else {
// Invalid UTF‑8 byte encountered
throw std::runtime_error("Invalid UTF‑8 encoding detected.");
}
length++; // Count one Unicode code point
}
return length;
}
int main() {
// Example UTF‑8 string containing Japanese characters
std::string text = u8"世界、こんにちは"; // "Hello world" in Japanese // kon-ni-chi-wa
// Print raw byte length
std::cout << "Byte length (std::string::size): " << text.size() << "\n";
// Print actual Unicode code point length
std::cout << "UTF‑8 code point length: " << utf8_length(text) << "\n";
}
/*
run:
Byte length (std::string::size): 24
UTF‑8 code point length: 8
*/