回答編集履歴

3

close不要

2018/05/24 03:17

投稿

yumetodo
yumetodo

スコア5850

test CHANGED
@@ -144,10 +144,6 @@
144
144
 
145
145
  ofs << utf_16_to_utf_8(L"あいうえお") << std::endl;
146
146
 
147
-
148
-
149
- ofs.close();
150
-
151
147
  }
152
148
 
153
149
  ```

2

convert

2018/05/24 03:17

投稿

yumetodo
yumetodo

スコア5850

test CHANGED
@@ -25,3 +25,129 @@
25
25
 
26
26
 
27
27
  でいけなかったっけか。
28
+
29
+
30
+
31
+ ---
32
+
33
+
34
+
35
+ > しかし、固定文字列ではなく
36
+
37
+
38
+
39
+ あー、そりゃそうだ。失礼、どうも寝ぼけていたようで。
40
+
41
+
42
+
43
+ > WideCharToMultiByte を使用する方法として、以下の記事を参考にして作成しましたが、16バイト目に無駄なNULL(0x00)が含まれていました。
44
+
45
+
46
+
47
+ まずUTF-8なbyte列で「ありうえお」を表現すると
48
+
49
+
50
+
51
+ ```
52
+
53
+ E3 81 82 E3 81 84 E3 81 86 E3 81 88 E3 81 8A
54
+
55
+ ```
56
+
57
+
58
+
59
+ のようになります。
60
+
61
+
62
+
63
+ ここで
64
+
65
+
66
+
67
+ > out2.txtがテキストエディタを使いUTF-8(BOMなし)で「あいうえお」という文字列を書き込んだファイル。
68
+
69
+
70
+
71
+ の出力と見比べると
72
+
73
+
74
+
75
+ ```
76
+
77
+ 0D 0A
78
+
79
+ ```
80
+
81
+
82
+
83
+ が余計についている事がわかりますが、これは言うまでもなくCR+LFですね(改行コード)。
84
+
85
+
86
+
87
+ > out.txtがプログラムで作成したテキストファイル。
88
+
89
+
90
+
91
+ の出力のこれも``std::endl`からきているものですね。
92
+
93
+
94
+
95
+ さて、NULL文字が含まれる原因は`wide_to_utf8_winapi`の実装がだめだからです。
96
+
97
+
98
+
99
+ 修正版がこちらです。
100
+
101
+
102
+
103
+ ```cpp
104
+
105
+ #include <string>
106
+
107
+ #include <windows.h>
108
+
109
+ #include <fstream>
110
+
111
+ #include <system_error>
112
+
113
+ std::string utf_16_to_utf_8(const std::wstring& str) {
114
+
115
+ static_assert(sizeof(wchar_t) == 2, "this function is windows only");
116
+
117
+ const int len = ::WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, nullptr, 0, nullptr, nullptr);
118
+
119
+ std::string re(len * 2, '\0');
120
+
121
+ if (!::WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, &re[0], len, nullptr, nullptr)) {
122
+
123
+ const auto er = ::GetLastError();
124
+
125
+ throw std::system_error(std::error_code(er, std::system_category()), "WideCharToMultiByte:(" + std::to_string(er) + ')');
126
+
127
+ }
128
+
129
+ const std::size_t real_len = std::char_traits<char>::length(re.c_str());
130
+
131
+ re.resize(real_len);
132
+
133
+ re.shrink_to_fit();
134
+
135
+ return re;
136
+
137
+ }
138
+
139
+ int main() {
140
+
141
+ std::ofstream ofs("out.txt");
142
+
143
+
144
+
145
+ ofs << utf_16_to_utf_8(L"あいうえお") << std::endl;
146
+
147
+
148
+
149
+ ofs.close();
150
+
151
+ }
152
+
153
+ ```

1

fstream

2018/05/24 03:10

投稿

yumetodo
yumetodo

スコア5850

test CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ```cpp
6
6
 
7
- #include <iostream>
7
+ #include<fstream>
8
8
 
9
9
 
10
10
 
@@ -12,7 +12,9 @@
12
12
 
13
13
  {
14
14
 
15
+ std::ofstream ofs("out.txt");
16
+
15
- std::cout << u8"ありきたり" << std::endl;
17
+ ofs << u8"ありきたり" << std::endl;
16
18
 
17
19
  }
18
20