Hàm mbrtowc() (Multibyte to Wide Character) chuyển đổi một chuỗi đa byte (multibyte string, thường là UTF-8) thành ký tự rộng (wchar_t). Đây là hàm an toàn, hỗ trợ trạng thái chuyển đổi (state-dependent encoding).
Chữ ký hàm
size_t mbrtowc(wchar_t *restrict wc, const char *restrict s, size_t n, mbstate_t *restrict ps);
Tham số
| Tham số | Ý nghĩa |
|---|---|
wc | Con trỏ lưu ký tự rộng kết quả (có thể NULL để chỉ đếm byte). |
s | Con trỏ đến chuỗi đa byte đầu vào. |
n | Số byte tối đa kiểm tra từ s. |
ps | Con trỏ trạng thái chuyển đổi (mbstate_t), dùng cho encoding có trạng thái. Truyền NULL để dùng trạng thái nội bộ tĩnh. |
Giá trị trả về
0: Ký tự null (chuỗi kết thúc).1..n: Số byte đã tiêu thụ để tạo ký tự rộng.(size_t)(-1): Lỗi encoding (dãy byte không hợp lệ), đặterrno = EILSEQ.(size_t)(-2): Chuỗi không đầy đủ (cần thêm byte), chuyển đổi chưa hoàn tất.
Ví dụ: Phân tích chuỗi UTF-8
#include <bits/stdc++.h> // GCC/Clang: bao gồm tất cả header chuẩn
#include <wchar.h>
#include <locale.h>
using namespace std;
void display(const char* s) {
mbstate_t ps = {}; // Trạng thái ban đầu (zero-initialized)
size_t len = strlen(s);
const char* end = s + len;
wchar_t wc;
size_t rc;
while ((rc = mbrtowc(&wc, s, end - s, &ps)) > 0) {
wcout << L"Ky tu: " << wc << L", so byte: " << rc << L'\n';
s += rc; // Tiến con trỏ
}
if (rc == (size_t)(-1)) wcout << L"Loi encoding!\n";
else if (rc == (size_t)(-2)) wcout << L"Chuoi khong day du!\n";
}
int main() {
// Thiết lập locale hỗ trợ UTF-8
setlocale(LC_ALL, "en_US.utf8");
// Chuỗi UTF-8: 'z' (1 byte), 'Ï' (2 byte), '簸' (3 byte), 'क' (3 byte)
const char* str = u8"z\u00cf\u7c38\U00000915";
display(str);
return 0;
}
Kết quả
Ky tu: z, so byte: 1 Ky tu: Ï, so byte: 2 Ky tu: 簸, so byte: 3 Ky tu: क, so byte: 3
Lưu ý quan trọng
- Luôn gọi
setlocale(LC_ALL, "")hoặc locale cụ thể (UTF-8) trước khi dùng hàm wide-char. mbstate_t ps = {};khởi tạo trạng thái zero (an toàn).- Dùng
wcoutđể inwchar_t; cần<iostream>và locale. - Để chuyển ngược (wide → multibyte), dùng
wcrtomb(). - C++11 cung cấp
std::wstring_convertvàstd::codecvt(deprecated C++17), hiện nay khuyên dùng ICU hoặcstd::from_chars/to_chars(chỉ số nguyên).
mbrtowc là công cụ cơ bản để xử lý Unicode trong C/C++ chuẩn, đặc biệt khi không thể dùng thư viện bên thứ ba.