回答編集履歴
4
m
test
CHANGED
@@ -208,6 +208,10 @@
|
|
208
208
|
|
209
209
|
|
210
210
|
|
211
|
+
[https://wandbox.org/permlink/sSSbwj1fHIyB06jH](https://wandbox.org/permlink/sSSbwj1fHIyB06jH)
|
212
|
+
|
213
|
+
|
214
|
+
|
211
215
|
なおより本格的に扱う場合はicuというライブラリを利用します。
|
212
216
|
|
213
217
|
|
3
ref
test
CHANGED
@@ -223,3 +223,9 @@
|
|
223
223
|
- [UTF-8文字リテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp17/utf8_character_literals.html)
|
224
224
|
|
225
225
|
- [UTF-8文字列リテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp11/utf8_string_literals.html)
|
226
|
+
|
227
|
+
- [svリテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/reference/string_view/basic_string_view/op_sv.html)
|
228
|
+
|
229
|
+
- [basic_string_view::substr - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/reference/string_view/basic_string_view/substr.html)
|
230
|
+
|
231
|
+
- [basic_string::コンストラクタ - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/reference/string/basic_string/op_constructor.html) (14)のコンストラクタを呼び出している
|
2
string
test
CHANGED
@@ -122,6 +122,96 @@
|
|
122
122
|
|
123
123
|
|
124
124
|
|
125
|
+
なお余談ですが、C++がCから受け継いだ文字列操作系関数はいくつもありますが、このうち多くの関数が安全に使うのが難しいものです。実際MSVCでは`_CRT_SECURE_NO_WARNINGS`なしではそれらの関数に警告を出すはずです。なのでもしC言語のような文字操作をするなら、`memcpy`を利用すると良いです。`strcpy`と違い、文字数より一つ多くバッファを確保しなければならないことを忘れる懸念は自分で明示的にNULL文字を代入しますから減りますし、実際MSVCは何も言ってきません。
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
しかしまあ、せっかくC++を使うのですからもう少しだけC++っぽく扱ってみましょう。`std::basic_string`とC++17で追加された`std::basic_string_view`を使います。`std::basic_string_view`を使って`std::basic_string`を構築するときに勝手にNULL文字終端する性質を利用しています。
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
```cpp
|
134
|
+
|
135
|
+
#include <iostream>
|
136
|
+
|
137
|
+
#include <string>
|
138
|
+
|
139
|
+
#include <string_view>
|
140
|
+
|
141
|
+
#include <stdexcept>
|
142
|
+
|
143
|
+
#if !defined(__cpp_char8_t)
|
144
|
+
|
145
|
+
using char8_t = char;
|
146
|
+
|
147
|
+
#endif
|
148
|
+
|
149
|
+
std::size_t charlen(const char8_t* s)
|
150
|
+
|
151
|
+
{
|
152
|
+
|
153
|
+
if (*s == 0) {
|
154
|
+
|
155
|
+
} else if ((*s & 0x80) == 0) {
|
156
|
+
|
157
|
+
return 1u;
|
158
|
+
|
159
|
+
} else if ((*s & 0xE0) == 0xC0) {
|
160
|
+
|
161
|
+
return 2u;
|
162
|
+
|
163
|
+
} else if ((*s & 0xF0) == 0xE0) {
|
164
|
+
|
165
|
+
return 3u;
|
166
|
+
|
167
|
+
} else if ((*s & 0xF8) == 0xF0) {
|
168
|
+
|
169
|
+
return 4u;
|
170
|
+
|
171
|
+
}
|
172
|
+
|
173
|
+
return 0;
|
174
|
+
|
175
|
+
}
|
176
|
+
|
177
|
+
auto extract_nth_char(std::basic_string_view<char8_t> s, std::size_t n)
|
178
|
+
|
179
|
+
{
|
180
|
+
|
181
|
+
std::size_t front_i = 0, len = 0, limit = n ? n - 1 : throw std::invalid_argument("0 is invalid");
|
182
|
+
|
183
|
+
for (std::size_t i = 0; i < limit; ++i, front_i += len = charlen(&s.data()[front_i]));
|
184
|
+
|
185
|
+
return s.substr(front_i, len);
|
186
|
+
|
187
|
+
}
|
188
|
+
|
189
|
+
int main()
|
190
|
+
|
191
|
+
{
|
192
|
+
|
193
|
+
using namespace std::literals;
|
194
|
+
|
195
|
+
const auto str = u8"あいうえお"sv;//string_viewになる
|
196
|
+
|
197
|
+
//std::basic_stringに変換することでNULL終端する
|
198
|
+
|
199
|
+
const std::basic_string<char8_t> dest{extract_nth_char(str, 3)};
|
200
|
+
|
201
|
+
//コンソールの文字エンコードがUTF-8だと仮定する
|
202
|
+
|
203
|
+
std::cout << reinterpret_cast<const char*>(dest.c_str()) << std::endl;
|
204
|
+
|
205
|
+
}
|
206
|
+
|
207
|
+
```
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
なおより本格的に扱う場合はicuというライブラリを利用します。
|
212
|
+
|
213
|
+
|
214
|
+
|
125
215
|
## 参照
|
126
216
|
|
127
217
|
|
1
ref
test
CHANGED
@@ -119,3 +119,17 @@
|
|
119
119
|
|
120
120
|
|
121
121
|
Windowsで動作させるときはWindows 10 1607よりあとのOSで、あらかじめ`chcp 65001`したコマンドプロンプトで実行してください。
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
## 参照
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
- [C++標準化委員会、ついに文字とは何かを理解する: char8_t](https://qiita.com/yumetodo/items/54e1a8230dbf513ea85b)
|
130
|
+
|
131
|
+
- [UTF-8エンコーディングされた文字の型として`char8_t`を追加 - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp20/char8_t.html)
|
132
|
+
|
133
|
+
- [UTF-8文字リテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp17/utf8_character_literals.html)
|
134
|
+
|
135
|
+
- [UTF-8文字列リテラル - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp11/utf8_string_literals.html)
|