質問編集履歴
4
環境を更新した旨追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
- MSYS2-MINGW64使用(※)
|
8
8
|
- MSVCのRuntimeを使用する
|
9
9
|
- libstdc++を使用する
|
10
|
-
- gccを使用する(現状12.2.0)
|
10
|
+
- gccを使用する(~~現状12.2.0~~ →13.2.0)
|
11
11
|
- MSYS2などの環境に依存せず、作成したバイナリは単品で動作する
|
12
12
|
- Windows 10以降はmustで、可能ならそれ以前でも正しく動作させたい
|
13
13
|
- MSYS2環境のbashで動かす場合、環境変数LC_*/LANG/LANGUAGEは未設定とする(LC_CTYPE=ja_JP.UTF-8は可)
|
@@ -251,4 +251,6 @@
|
|
251
251
|
普段使いしてる人の正しい日本語の扱い方を知りたい
|
252
252
|
|
253
253
|
### 補足情報(FW/ツールのバージョンなど)
|
254
|
-
msys/msys2-runtime 3.4.6-2
|
254
|
+
msys/msys2-runtime ~~3.4.6-2~~ → 3.4.10-2
|
255
|
+
|
256
|
+
※デバッグ用のシンボル情報が欲しくて最新バージョンに更新してビルドしました(2023/12/18)。
|
3
作業中にうっかりmsys2環境の更新をしてしまったので、ランタイムバージョンを変更(質問/回答内容の再現確認は実施済み)
test
CHANGED
File without changes
|
test
CHANGED
@@ -251,6 +251,4 @@
|
|
251
251
|
普段使いしてる人の正しい日本語の扱い方を知りたい
|
252
252
|
|
253
253
|
### 補足情報(FW/ツールのバージョンなど)
|
254
|
-
msys/msys2-runtime 3.
|
254
|
+
msys/msys2-runtime 3.4.6-2
|
255
|
-
|
256
|
-
|
2
文字数制限を気にしつつ誤解のないように説明的文言を加筆した。
test
CHANGED
File without changes
|
test
CHANGED
@@ -4,15 +4,18 @@
|
|
4
4
|
|
5
5
|
### 前提
|
6
6
|
|
7
|
-
- MSYS2-MINGW64使用
|
7
|
+
- MSYS2-MINGW64使用(※)
|
8
8
|
- MSVCのRuntimeを使用する
|
9
9
|
- libstdc++を使用する
|
10
10
|
- gccを使用する(現状12.2.0)
|
11
11
|
- MSYS2などの環境に依存せず、作成したバイナリは単品で動作する
|
12
12
|
- Windows 10以降はmustで、可能ならそれ以前でも正しく動作させたい
|
13
13
|
- MSYS2環境のbashで動かす場合、環境変数LC_*/LANG/LANGUAGEは未設定とする(LC_CTYPE=ja_JP.UTF-8は可)
|
14
|
-
|
14
|
+
- 端末(conhost/mintty/etc...)は何でもいいし、適宜設定は変更するものとするが、原則デフォルトの状態で動作すること
|
15
|
+
- 日本語Windowsの場合、システムロケールのコードページは932でも65002でもどちらでも動作するものする
|
16
|
+
- 紐付けられた端末があり、端末への出力が実際にある場合、端末のコードページには追従してもいいし、しなくてもいいが、システムロケールのコードページと端末のコードページのいずれかで入出力できていること
|
17
|
+
|
15
|
-
参考
|
18
|
+
※参考
|
16
19
|
https://www.msys2.org/docs/environments/
|
17
20
|
|
18
21
|
### 質問
|
@@ -26,7 +29,7 @@
|
|
26
29
|
※ソースコードは次節参照
|
27
30
|
|
28
31
|
#### (1) std::coutに出力するケース
|
29
|
-
ビルドと実行(システムロケールはコードページ932でmsys環境(mintty)で実施)
|
32
|
+
ビルドと実行(システムロケールはコードページ932でmsys2環境(mintty)で実施)
|
30
33
|
```bash
|
31
34
|
$ g++ -g -Wall -static hello.cpp -o hello
|
32
35
|
$ env | grep LANG
|
@@ -37,6 +40,8 @@
|
|
37
40
|
|
38
41
|
$
|
39
42
|
```
|
43
|
+
msys2環境のminttyの設定はja_JPのUTF-8にしようが、defaultのままにしようが、同じです。
|
44
|
+
一言で言えば、この状態からcmd /c "dir"したときに日本語が化けないのと同様の、CP932→UTF-8の変換が「どこかで」かかっている文字の化け方をしています。
|
40
45
|
|
41
46
|
#### (2) std::wcoutに出力するケース
|
42
47
|
```bash
|
@@ -45,6 +50,7 @@
|
|
45
50
|
|
46
51
|
$
|
47
52
|
```
|
53
|
+
これは端末以前に何も出力されていないことを示しています。(実際にパイプで繋いでも何も出ていません。)
|
48
54
|
|
49
55
|
### 該当のソースコード
|
50
56
|
|
@@ -93,7 +99,7 @@
|
|
93
99
|
$
|
94
100
|
```
|
95
101
|
iconvでシフトJISに変換出力してみたが、さらに文字化けするだけだった
|
96
|
-
変換は正しく実施されている
|
102
|
+
hexdumpの結果を見る限り変換は正しく実施されている
|
97
103
|
|
98
104
|
#### (3) catを噛ませてみる
|
99
105
|
```bash
|
@@ -110,7 +116,8 @@
|
|
110
116
|
|
111
117
|
$
|
112
118
|
```
|
113
|
-
MSYS2のcatを噛ませると同じ内容でも正しく表示される
|
119
|
+
MSYS2のcatを噛ませると、同じ内容(hexdumpの結果からUTF-8と分かる)でも「なぜか」正しく表示される。
|
120
|
+
bash/minttyへの出力方法が./helloとcatで異なっていて、その区別から./helloだけCP932→UTF-8変換をかけられていると推測する。
|
114
121
|
|
115
122
|
#### (4) cmdから見てみる
|
116
123
|
```cmd
|
@@ -131,7 +138,7 @@
|
|
131
138
|
```
|
132
139
|
※conhost.exe上のcmd.exe(minttyなどMSYS2環境ではなく、純粋なWindows環境)
|
133
140
|
|
134
|
-
コマンドプロンプトからでも(3)の現象は同様に再現する。
|
141
|
+
コマンドプロンプトからでも(3)の現象は同様に再現する。また環境変数の影響でもなく、cmdは子プロセスに変換などの細工をしないので、helloは素直にUTF-8で出力していることが確定し、catが単体でUTF-8→CP932の変換をしているということが分かる。
|
135
142
|
|
136
143
|
#### (5) 絵文字を出力させてみる
|
137
144
|
```bash
|
@@ -156,7 +163,7 @@
|
|
156
163
|
|
157
164
|
$
|
158
165
|
```
|
159
|
-
絵文字を表示可能なことから、シフトJISで表示しようとしていないことが分かる。
|
166
|
+
絵文字を表示可能なことから、シフトJISで表示しようとしていないことが分かる。さらに具体的に言えば、bashやcatがパイプからの読み込み時に変換をかけていないこと、受け取ったminttyも変換していないことが分かる。
|
160
167
|
|
161
168
|
#### (6) リテラルをシフトJISとしてコンパイルさせる
|
162
169
|
```bash
|
@@ -227,17 +234,19 @@
|
|
227
234
|
$
|
228
235
|
```
|
229
236
|
システムロケールへの設定はできない→wcoutは使えない
|
230
|
-
(https://stackoverflow.com/a/20181564)
|
237
|
+
(https://stackoverflow.com/a/20181564)。
|
238
|
+
より正確にはwcoutは日本語の出力ができない。libstdc++がgnuモデル以外(今回はgeneralモデル)での変換を実装していないため。
|
231
239
|
|
232
240
|
#### (9) 調べたことまとめ
|
233
241
|
上記から、MINGW64で正しく日本語を扱うには、
|
234
242
|
- wcoutを使わず、coutを使う
|
235
|
-
- msvcrtかWindowsAPIか外部ライブラリなどを使って自分でエンコーディングを変換する
|
243
|
+
- msvcrtかWindowsAPIか外部ライブラリなどを使って自分でエンコーディングを(システムロケールのコードページか端末のコードページに)変換する
|
236
244
|
- リテラルをマルチバイトの固定エンコーディングにする(シフトJISなど)とワイド文字経由のコードページ変換が2度必要になり、手間がかかるため、ワイド文字列のリテラルか、u8プレフィックス付きを使うべき(ただしC++20でchar型での扱いができなくなる)
|
237
245
|
なのかと思う
|
238
246
|
|
239
247
|
ただマルチバイト(cout)にすると、
|
240
248
|
- 入出力時に変換が必要になり、わざわざマルチバイトにして出力した文字列をWin32側でまたワイド文字列に戻すなどの処理が入りそう
|
249
|
+
これはそもそもWriteConsoleWがワイド文字列を受け取れるから。
|
241
250
|
|
242
251
|
普段使いしてる人の正しい日本語の扱い方を知りたい
|
243
252
|
|
1
一応minttyの設定も必要部分に記述した
test
CHANGED
File without changes
|
test
CHANGED
@@ -171,7 +171,7 @@
|
|
171
171
|
|
172
172
|
$
|
173
173
|
```
|
174
|
-
シフトJISとして出力されており、正しく表示されている。
|
174
|
+
シフトJISとして出力されており、正しく表示されている(minttyはロケールCの文字セットUTF-8)。
|
175
175
|
|
176
176
|
#### (7) 依存DLLを調べる
|
177
177
|
```bash
|