C++: UTF-8 の文字列を1文字ずつ表示する (std::string)
- C++: 文字列の一部を取り出す (std::string)
- C++: Mac OSX で std::wcout を使ってワイド文字を表示させようとするとクラッシュする
- C++ : wchar_t、char32_t、char16_t 型の文字列の長さを求める
- C++: std::wstring、std::u32string、std::u16string を1文字ずつ表示する
- C++: std::wstring、std::u32string、std::u16string と c_str メソッドの戻り値について
- C++: 文字列を連結する
- C++: 文字列イテレーターのインデックスを求める
- C++: UTF-8 の文字列を1文字ずつ表示する (std::string)
- C++: UTF-8 の文字列の長さを求める (std::string)
- C++: コードポイントから UTF-8 の文字を生成する (std::string)
std::u32string、std::u16string などで1文字ずつ表示することを行ったが、今度は std::string もやってみた。コードをかんたんにするために、不正なバイト列を考慮していない。
#include <iostream> #include <string> void print_each_char(std::string); int main(void) { using namespace std; string str = u8"𠮷野家のコピペ"; print_each_char(str); return 0; } void print_each_char(std::string str) { using namespace std; int pos; unsigned char lead; int char_size; for (pos = 0; pos < str.size(); pos += char_size) { lead = str[pos]; if (lead < 0x80) { char_size = 1; } else if (lead < 0xE0) { char_size = 2; } else if (lead < 0xF0) { char_size = 3; } else { char_size = 4; } cout << str.substr(pos, char_size) << '\n'; } }
イテレーターを使うと次のようになる。
#include <iostream> #include <string> void print_each_char(std::string); int main(void) { using namespace std; string str = u8"𠮷野家のコピペ"; print_each_char(str); return 0; } void print_each_char(std::string str) { using namespace std; unsigned char lead; int char_size = 0; for (string::iterator it = str.begin(); it != str.end(); it += char_size) { lead = *it; if (lead < 0x80) { char_size = 1; } else if (lead < 0xE0) { char_size = 2; } else if (lead < 0xF0) { char_size = 3; } else { char_size = 4; } cout << str.substr(distance(str.begin(), it), char_size) << '\n'; } }
戻り値にタプルを使った例は次のとおり。
#include <iostream> #include <string> std::tuple<std::string, int> utf8_next_char(std::string str, int str_size, int pos); int main(void) { using namespace std; string str = u8"あいうえお"; tuple<string, int> t; int str_size = str.size(); int pos = 0; string buf; int buf_size = 0; for (int pos = 0; pos < str_size; pos += buf_size) { t = utf8_next_char(str, str_size, pos); buf = get<0>(t); buf_size = get<1>(t); cout << buf << '\n'; } return 0; } std::tuple<std::string, int> utf8_next_char(std::string str, int str_size, int pos) { using namespace std; unsigned char c; string buf; int buf_size; if (pos >= str_size) { return make_tuple(u8"?", pos); } c = str[pos]; if (c < 0x80) { buf_size = 1; } else if (c < 0xE0) { buf_size = 2; } else if (c < 0xF0){ buf_size = 3; } else { buf_size = 4; } buf = str.substr(pos, buf_size); return make_tuple(buf, buf_size); }