回答編集履歴
4
m
answer
CHANGED
@@ -103,6 +103,8 @@
|
|
103
103
|
}
|
104
104
|
```
|
105
105
|
|
106
|
+
[https://wandbox.org/permlink/sSSbwj1fHIyB06jH](https://wandbox.org/permlink/sSSbwj1fHIyB06jH)
|
107
|
+
|
106
108
|
なおより本格的に扱う場合はicuというライブラリを利用します。
|
107
109
|
|
108
110
|
## 参照
|
3
ref
answer
CHANGED
@@ -110,4 +110,7 @@
|
|
110
110
|
- [C++標準化委員会、ついに文字とは何かを理解する: char8_t](https://qiita.com/yumetodo/items/54e1a8230dbf513ea85b)
|
111
111
|
- [UTF-8エンコーディングされた文字の型として`char8_t`を追加 - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp20/char8_t.html)
|
112
112
|
- [UTF-8文字リテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp17/utf8_character_literals.html)
|
113
|
-
- [UTF-8文字列リテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp11/utf8_string_literals.html)
|
113
|
+
- [UTF-8文字列リテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp11/utf8_string_literals.html)
|
114
|
+
- [svリテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/reference/string_view/basic_string_view/op_sv.html)
|
115
|
+
- [basic_string_view::substr - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/reference/string_view/basic_string_view/substr.html)
|
116
|
+
- [basic_string::コンストラクタ - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/reference/string/basic_string/op_constructor.html) (14)のコンストラクタを呼び出している
|
2
string
answer
CHANGED
@@ -60,6 +60,51 @@
|
|
60
60
|
|
61
61
|
Windowsで動作させるときはWindows 10 1607よりあとのOSで、あらかじめ`chcp 65001`したコマンドプロンプトで実行してください。
|
62
62
|
|
63
|
+
なお余談ですが、C++がCから受け継いだ文字列操作系関数はいくつもありますが、このうち多くの関数が安全に使うのが難しいものです。実際MSVCでは`_CRT_SECURE_NO_WARNINGS`なしではそれらの関数に警告を出すはずです。なのでもしC言語のような文字操作をするなら、`memcpy`を利用すると良いです。`strcpy`と違い、文字数より一つ多くバッファを確保しなければならないことを忘れる懸念は自分で明示的にNULL文字を代入しますから減りますし、実際MSVCは何も言ってきません。
|
64
|
+
|
65
|
+
しかしまあ、せっかくC++を使うのですからもう少しだけC++っぽく扱ってみましょう。`std::basic_string`とC++17で追加された`std::basic_string_view`を使います。`std::basic_string_view`を使って`std::basic_string`を構築するときに勝手にNULL文字終端する性質を利用しています。
|
66
|
+
|
67
|
+
```cpp
|
68
|
+
#include <iostream>
|
69
|
+
#include <string>
|
70
|
+
#include <string_view>
|
71
|
+
#include <stdexcept>
|
72
|
+
#if !defined(__cpp_char8_t)
|
73
|
+
using char8_t = char;
|
74
|
+
#endif
|
75
|
+
std::size_t charlen(const char8_t* s)
|
76
|
+
{
|
77
|
+
if (*s == 0) {
|
78
|
+
} else if ((*s & 0x80) == 0) {
|
79
|
+
return 1u;
|
80
|
+
} else if ((*s & 0xE0) == 0xC0) {
|
81
|
+
return 2u;
|
82
|
+
} else if ((*s & 0xF0) == 0xE0) {
|
83
|
+
return 3u;
|
84
|
+
} else if ((*s & 0xF8) == 0xF0) {
|
85
|
+
return 4u;
|
86
|
+
}
|
87
|
+
return 0;
|
88
|
+
}
|
89
|
+
auto extract_nth_char(std::basic_string_view<char8_t> s, std::size_t n)
|
90
|
+
{
|
91
|
+
std::size_t front_i = 0, len = 0, limit = n ? n - 1 : throw std::invalid_argument("0 is invalid");
|
92
|
+
for (std::size_t i = 0; i < limit; ++i, front_i += len = charlen(&s.data()[front_i]));
|
93
|
+
return s.substr(front_i, len);
|
94
|
+
}
|
95
|
+
int main()
|
96
|
+
{
|
97
|
+
using namespace std::literals;
|
98
|
+
const auto str = u8"あいうえお"sv;//string_viewになる
|
99
|
+
//std::basic_stringに変換することでNULL終端する
|
100
|
+
const std::basic_string<char8_t> dest{extract_nth_char(str, 3)};
|
101
|
+
//コンソールの文字エンコードがUTF-8だと仮定する
|
102
|
+
std::cout << reinterpret_cast<const char*>(dest.c_str()) << std::endl;
|
103
|
+
}
|
104
|
+
```
|
105
|
+
|
106
|
+
なおより本格的に扱う場合はicuというライブラリを利用します。
|
107
|
+
|
63
108
|
## 参照
|
64
109
|
|
65
110
|
- [C++標準化委員会、ついに文字とは何かを理解する: char8_t](https://qiita.com/yumetodo/items/54e1a8230dbf513ea85b)
|
1
ref
answer
CHANGED
@@ -58,4 +58,11 @@
|
|
58
58
|
|
59
59
|
[https://wandbox.org/permlink/BIkWAMmrI0t1KHa6](https://wandbox.org/permlink/BIkWAMmrI0t1KHa6)
|
60
60
|
|
61
|
-
Windowsで動作させるときはWindows 10 1607よりあとのOSで、あらかじめ`chcp 65001`したコマンドプロンプトで実行してください。
|
61
|
+
Windowsで動作させるときはWindows 10 1607よりあとのOSで、あらかじめ`chcp 65001`したコマンドプロンプトで実行してください。
|
62
|
+
|
63
|
+
## 参照
|
64
|
+
|
65
|
+
- [C++標準化委員会、ついに文字とは何かを理解する: char8_t](https://qiita.com/yumetodo/items/54e1a8230dbf513ea85b)
|
66
|
+
- [UTF-8エンコーディングされた文字の型として`char8_t`を追加 - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp20/char8_t.html)
|
67
|
+
- [UTF-8文字リテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp17/utf8_character_literals.html)
|
68
|
+
- [UTF-8文字列リテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp11/utf8_string_literals.html)
|