回答編集履歴

8

C++の確認プログラムでコードとバイナリを名前を変えて保存できるようにし、ビルドしてシステムロケールを変えてから同じバイナリで再確認できるようにした。

2023/12/14 05:32

投稿

dameo
dameo

スコア943

test CHANGED
@@ -180,8 +180,10 @@
180
180
  #include <cstdlib>
181
181
  #include <windows.h>
182
182
  using namespace std;
183
- int main() {
183
+ int main(int argc, char* argv[]) {
184
184
  setlocale(LC_CTYPE, "C");
185
+
186
+ bool build = (argc == 1); // 引数が1つでも指定されてたらビルドしない
185
187
  UINT cps[] = { 932, CP_UTF8 };
186
188
  constexpr size_t CP_COUNT = sizeof(cps) / sizeof(cps[0]);
187
189
  wstring strs[] = { L"こんにちは世界!", L"😊" };
@@ -203,8 +205,10 @@
203
205
  string u8str(bytes, l);
204
206
 
205
207
  for (string loc : {"", "C", ".932", ".UTF-8"}) {
208
+ string fname = string("hello_locale_") + to_string(cps[cp]) + "_" + out + "_" + loc + "_" + to_string(i);
209
+ if (build) {
206
- ofstream f("hello_locale_x.cpp");
210
+ ofstream f("hello_locale_x.cpp");
207
- f << "\
211
+ f << "\
208
212
  \xEF\xBB\xBF\
209
213
  #include <iostream>\n\
210
214
  int main()\n\
@@ -213,12 +217,19 @@
213
217
  std::" << out << " << " << prefix << "\"" << u8str << "\";\n\
214
218
  return 0;\n\
215
219
  }";
216
- f.close();
220
+ f.close();
217
- auto r = system("cmake --build build >NUL");
221
+ auto r = system("cmake --build build >NUL");
218
- if (r != 0) return 1;
222
+ if (r != 0) return 1;
223
+ system("copy .\\build\\Debug\\hello_locale_x.exe . >nul");
224
+ system((string("copy hello_locale_x.exe ") + fname + ".exe >nul").c_str());
225
+ system((string("copy hello_locale_x.cpp ") + fname + ".cpp >nul").c_str());
226
+ }
227
+ else {
228
+ system((string("copy " + fname + ".exe hello_locale_x.exe >nul")).c_str());
229
+ }
219
230
  cout << "|" << cps[cp] << "| MSVC++ |" << out << "|\"" << loc << "\"|" << prefix << "\"" << cpstr << "\"|";
220
231
  cout.flush();
221
- system(".\\build\\Debug\\hello_locale_x");
232
+ system(".\\hello_locale_x");
222
233
  cout << "|" << endl;
223
234
  }
224
235
  }

7

powershellもUTF16LEに直したりするのでC++で書き直した

2023/12/14 00:53

投稿

dameo
dameo

スコア943

test CHANGED
@@ -171,74 +171,101 @@
171
171
  add_executable (hello_locale_x "hello_locale_x.cpp" )
172
172
  ```
173
173
 
174
- ``cmake -B build -S .``くらいしてからpowershellを流す。
174
+ ``cmake -B build -S .``くらいしてから~~powershellを流す。~~以下のC++プログラムを流します。
175
+
175
-
176
+ ```C++
177
+ #include <iostream>
178
+ #include <string>
179
+ #include <fstream>
180
+ #include <cstdlib>
181
+ #include <windows.h>
182
+ using namespace std;
176
- ```powershell
183
+ int main() {
184
+ setlocale(LC_CTYPE, "C");
185
+ UINT cps[] = { 932, CP_UTF8 };
186
+ constexpr size_t CP_COUNT = sizeof(cps) / sizeof(cps[0]);
177
- foreach($cp in "932", "65001") {
187
+ wstring strs[] = { L"こんにちは世界!", L"😊" };
188
+ constexpr size_t TEST_COUNT = sizeof(strs) / sizeof(strs[0]);
189
+
178
- chcp $cp;
190
+ for (int cp = 0; cp < CP_COUNT; ++cp) {
191
+ system((string("chcp ") + to_string(cps[cp])).c_str());
179
- foreach($out in "cout", "wcout") {
192
+ for (string out : {"cout", "wcout"}) {
193
+ string prefix;
180
- if ($out -eq "wcout") {
194
+ if (out == string("wcout")) {
181
- $prefix="L";
195
+ prefix = "L";
196
+ }
197
+ for (int i = 0; i < TEST_COUNT; ++i) {
182
- } else {
198
+ char bytes[100];
199
+ constexpr int BYTES_COUNT = sizeof(bytes) / sizeof(bytes[0]);
200
+ auto l = WideCharToMultiByte(cps[cp], 0, strs[i].c_str(), static_cast<int>(strs[i].size()), bytes, BYTES_COUNT, cps[cp] == CP_UTF8 ? NULL : "?", NULL);
201
+ string cpstr(bytes, l);
202
+ l = WideCharToMultiByte(CP_UTF8, 0, strs[i].c_str(), static_cast<int>(strs[i].size()), bytes, BYTES_COUNT, NULL, NULL);
203
+ string u8str(bytes, l);
204
+
205
+ for (string loc : {"", "C", ".932", ".UTF-8"}) {
206
+ ofstream f("hello_locale_x.cpp");
183
- $prefix="";
207
+ f << "\
208
+ \xEF\xBB\xBF\
209
+ #include <iostream>\n\
210
+ int main()\n\
211
+ {\n\
212
+ std::setlocale(LC_CTYPE, \"" << loc << "\");\n\
213
+ std::" << out << " << " << prefix << "\"" << u8str << "\";\n\
214
+ return 0;\n\
215
+ }";
216
+ f.close();
217
+ auto r = system("cmake --build build >NUL");
218
+ if (r != 0) return 1;
219
+ cout << "|" << cps[cp] << "| MSVC++ |" << out << "|\"" << loc << "\"|" << prefix << "\"" << cpstr << "\"|";
220
+ cout.flush();
221
+ system(".\\build\\Debug\\hello_locale_x");
222
+ cout << "|" << endl;
223
+ }
224
+ }
184
225
  }
185
- foreach($str in "こんにちは世界!", "😊") {
186
- foreach($loc in "","C",".932",".UTF-8") {
187
- echo @"
188
- #include <iostream>
189
- int main()
190
- {
191
- std::setlocale(LC_CTYPE,"${loc}");
192
- std::${out}<<${prefix}"${str}";
226
+ cerr << "press enter" << endl;
227
+ string _;
228
+ std::getline(cin, _);
229
+ }
230
+ system("chcp 932");
193
231
  return 0;
194
232
  }
195
- "@ >hello_locale_x.cpp;
196
- cmake --build build | Out-Null;
197
- $result = .\build\Debug\hello_locale_x;
198
- echo "|$cp|MSVC++|$out|""$loc""|$prefix""$str""|$result|"
199
- }
200
- }
201
- }
202
- "press enter";
203
- $host.UI.RawUI.ReadKey();
204
- }
205
- chcp 932;
206
233
  ```
207
234
  ### 結果(mintty)
208
235
  |端末コードページ|処理系|出力先|ロケール(C)|リテラル(ソースUTF8)|結果|
209
236
  |:--|:--:|:--:|:--|:--|:--|
210
- |932|MSVC++|cout|""|"こんにちは世界!"|こんにちは世界!|
237
+ |932| MSVC++ |cout|""|"こんにちは世界!"|こんにちは世界!|
211
- |932|MSVC++|cout|"C"|"こんにちは世界!"|こんにちは世界!|
238
+ |932| MSVC++ |cout|"C"|"こんにちは世界!"|こんにちは世界!|
212
- |932|MSVC++|cout|".932"|"こんにちは世界!"|こんにちは世界!|
239
+ |932| MSVC++ |cout|".932"|"こんにちは世界!"|こんにちは世界!|
213
- |932|MSVC++|cout|".UTF-8"|"こんにちは世界!"|こんにちは世界!|
240
+ |932| MSVC++ |cout|".UTF-8"|"こんにちは世界!"||
214
- |932|MSVC++|cout|""|"😊"|??|
241
+ |932| MSVC++ |cout|""|"😊"|??|
215
- |932|MSVC++|cout|"C"|"😊"|??|
242
+ |932| MSVC++ |cout|"C"|"😊"|??|
216
- |932|MSVC++|cout|".932"|"😊"|??|
243
+ |932| MSVC++ |cout|".932"|"😊"|??|
217
- |932|MSVC++|cout|".UTF-8"|"😊"|??|
244
+ |932| MSVC++ |cout|".UTF-8"|"😊"|??|
218
- |932|MSVC++|wcout|""|L"こんにちは世界!"|こんにちは世界!|
245
+ |932| MSVC++ |wcout|""|L"こんにちは世界!"|こんにちは世界!|
219
- |932|MSVC++|wcout|"C"|L"こんにちは世界!"||
246
+ |932| MSVC++ |wcout|"C"|L"こんにちは世界!"||
220
- |932|MSVC++|wcout|".932"|L"こんにちは世界!"|こんにちは世界!|
247
+ |932| MSVC++ |wcout|".932"|L"こんにちは世界!"|こんにちは世界!|
221
- |932|MSVC++|wcout|".UTF-8"|L"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
248
+ |932| MSVC++ |wcout|".UTF-8"|L"こんにちは世界!"|こんにちは世界!|
222
- |932|MSVC++|wcout|""|L"😊"||
249
+ |932| MSVC++ |wcout|""|L"😊"||
223
- |932|MSVC++|wcout|"C"|L"😊"||
250
+ |932| MSVC++ |wcout|"C"|L"😊"||
224
- |932|MSVC++|wcout|".932"|L"😊"||
251
+ |932| MSVC++ |wcout|".932"|L"😊"||
225
- |932|MSVC++|wcout|".UTF-8"|L"😊"||
252
+ |932| MSVC++ |wcout|".UTF-8"|L"😊"||
226
- |65001|MSVC++|cout|""|"こんにちは世界!"|こんにちは世界!|
253
+ |65001| MSVC++ |cout|""|"こんにちは世界!"|こんにちは世界!|
227
- |65001|MSVC++|cout|"C"|"こんにちは世界!"|こんにちは世界!|
254
+ |65001| MSVC++ |cout|"C"|"こんにちは世界!"|ɂ͐EI|
228
- |65001|MSVC++|cout|".932"|"こんにちは世界!"|こんにちは世界!|
255
+ |65001| MSVC++ |cout|".932"|"こんにちは世界!"|こんにちは世界!|
229
- |65001|MSVC++|cout|".UTF-8"|"こんにちは世界!"|こんにちは世界!|
256
+ |65001| MSVC++ |cout|".UTF-8"|"こんにちは世界!"||
230
- |65001|MSVC++|cout|""|"😊"|??|
257
+ |65001| MSVC++ |cout|""|"😊"|??|
231
- |65001|MSVC++|cout|"C"|"😊"|??|
258
+ |65001| MSVC++ |cout|"C"|"😊"|??|
232
- |65001|MSVC++|cout|".932"|"😊"|??|
259
+ |65001| MSVC++ |cout|".932"|"😊"|??|
233
- |65001|MSVC++|cout|".UTF-8"|"😊"|??|
260
+ |65001| MSVC++ |cout|".UTF-8"|"😊"|??|
234
- |65001|MSVC++|wcout|""|L"こんにちは世界!"|こんにちは世界!|
261
+ |65001| MSVC++ |wcout|""|L"こんにちは世界!"|こんにちは世界!|
235
- |65001|MSVC++|wcout|"C"|L"こんにちは世界!"||
262
+ |65001| MSVC++ |wcout|"C"|L"こんにちは世界!"||
236
- |65001|MSVC++|wcout|".932"|L"こんにちは世界!"|こんにちは世界!|
263
+ |65001| MSVC++ |wcout|".932"|L"こんにちは世界!"|こんにちは世界!|
237
- |65001|MSVC++|wcout|".UTF-8"|L"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
264
+ |65001| MSVC++ |wcout|".UTF-8"|L"こんにちは世界!"|こんにちは世界!|
238
- |65001|MSVC++|wcout|""|L"😊"||
265
+ |65001| MSVC++ |wcout|""|L"😊"||
239
- |65001|MSVC++|wcout|"C"|L"😊"||
266
+ |65001| MSVC++ |wcout|"C"|L"😊"||
240
- |65001|MSVC++|wcout|".932"|L"😊"||
267
+ |65001| MSVC++ |wcout|".932"|L"😊"||
241
- |65001|MSVC++|wcout|".UTF-8"|L"😊"||
268
+ |65001| MSVC++ |wcout|".UTF-8"|L"😊"||
242
269
 
243
270
  ### 結果(コマンドプロンプト)
244
271
  😊が表示不可能だけで同じ

6

CMakeがデフォルトだとマルチバイトだったのでUNICODE定義を追加(結果は変わらず)

2023/12/13 11:19

投稿

dameo
dameo

スコア943

test CHANGED
@@ -167,6 +167,7 @@
167
167
  ```CMake
168
168
  cmake_minimum_required (VERSION 3.8)
169
169
  project ("hello_locale_x")
170
+ add_definitions(-DUNICODE -D_UNICODE)
170
171
  add_executable (hello_locale_x "hello_locale_x.cpp" )
171
172
  ```
172
173
 

5

cmakeの使い方書き忘れたので追記

2023/12/13 10:08

投稿

dameo
dameo

スコア943

test CHANGED
@@ -169,6 +169,9 @@
169
169
  project ("hello_locale_x")
170
170
  add_executable (hello_locale_x "hello_locale_x.cpp" )
171
171
  ```
172
+
173
+ ``cmake -B build -S .``くらいしてからpowershellを流す。
174
+
172
175
  ```powershell
173
176
  foreach($cp in "932", "65001") {
174
177
  chcp $cp;

4

VC++での確認を追記

2023/12/13 10:00

投稿

dameo
dameo

スコア943

test CHANGED
@@ -160,3 +160,84 @@
160
160
  なので、現時点でVC++で作成したアプリと近い動きを期待する(locale設定に""を使い、システムロケールに依存した動きにする)ためには、**UCRT64でワイド文字列リテラルとwcoutを使うことが望ましい**と予想する。ただし**絵文字(他にもあるかも)は諦める必要がある**。
161
161
 
162
162
  次はVC++でのUCRTの動きと、コマンドプロンプト上での動作確認でしょうか。。。
163
+
164
+ ## VC++でビルドしたものを動作確認
165
+ 絵文字表示が可能な端末が必要だったのでminttyでも確認。ビルドはVS2019を使用。
166
+ ### スクリプト
167
+ ```CMake
168
+ cmake_minimum_required (VERSION 3.8)
169
+ project ("hello_locale_x")
170
+ add_executable (hello_locale_x "hello_locale_x.cpp" )
171
+ ```
172
+ ```powershell
173
+ foreach($cp in "932", "65001") {
174
+ chcp $cp;
175
+ foreach($out in "cout", "wcout") {
176
+ if ($out -eq "wcout") {
177
+ $prefix="L";
178
+ } else {
179
+ $prefix="";
180
+ }
181
+ foreach($str in "こんにちは世界!", "😊") {
182
+ foreach($loc in "","C",".932",".UTF-8") {
183
+ echo @"
184
+ #include <iostream>
185
+ int main()
186
+ {
187
+ std::setlocale(LC_CTYPE,"${loc}");
188
+ std::${out}<<${prefix}"${str}";
189
+ return 0;
190
+ }
191
+ "@ >hello_locale_x.cpp;
192
+ cmake --build build | Out-Null;
193
+ $result = .\build\Debug\hello_locale_x;
194
+ echo "|$cp|MSVC++|$out|""$loc""|$prefix""$str""|$result|"
195
+ }
196
+ }
197
+ }
198
+ "press enter";
199
+ $host.UI.RawUI.ReadKey();
200
+ }
201
+ chcp 932;
202
+ ```
203
+ ### 結果(mintty)
204
+ |端末コードページ|処理系|出力先|ロケール(C)|リテラル(ソースUTF8)|結果|
205
+ |:--|:--:|:--:|:--|:--|:--|
206
+ |932|MSVC++|cout|""|"こんにちは世界!"|こんにちは世界!|
207
+ |932|MSVC++|cout|"C"|"こんにちは世界!"|こんにちは世界!|
208
+ |932|MSVC++|cout|".932"|"こんにちは世界!"|こんにちは世界!|
209
+ |932|MSVC++|cout|".UTF-8"|"こんにちは世界!"|こんにちは世界!|
210
+ |932|MSVC++|cout|""|"😊"|??|
211
+ |932|MSVC++|cout|"C"|"😊"|??|
212
+ |932|MSVC++|cout|".932"|"😊"|??|
213
+ |932|MSVC++|cout|".UTF-8"|"😊"|??|
214
+ |932|MSVC++|wcout|""|L"こんにちは世界!"|こんにちは世界!|
215
+ |932|MSVC++|wcout|"C"|L"こんにちは世界!"||
216
+ |932|MSVC++|wcout|".932"|L"こんにちは世界!"|こんにちは世界!|
217
+ |932|MSVC++|wcout|".UTF-8"|L"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
218
+ |932|MSVC++|wcout|""|L"😊"||
219
+ |932|MSVC++|wcout|"C"|L"😊"||
220
+ |932|MSVC++|wcout|".932"|L"😊"||
221
+ |932|MSVC++|wcout|".UTF-8"|L"😊"||
222
+ |65001|MSVC++|cout|""|"こんにちは世界!"|こんにちは世界!|
223
+ |65001|MSVC++|cout|"C"|"こんにちは世界!"|こんにちは世界!|
224
+ |65001|MSVC++|cout|".932"|"こんにちは世界!"|こんにちは世界!|
225
+ |65001|MSVC++|cout|".UTF-8"|"こんにちは世界!"|こんにちは世界!|
226
+ |65001|MSVC++|cout|""|"😊"|??|
227
+ |65001|MSVC++|cout|"C"|"😊"|??|
228
+ |65001|MSVC++|cout|".932"|"😊"|??|
229
+ |65001|MSVC++|cout|".UTF-8"|"😊"|??|
230
+ |65001|MSVC++|wcout|""|L"こんにちは世界!"|こんにちは世界!|
231
+ |65001|MSVC++|wcout|"C"|L"こんにちは世界!"||
232
+ |65001|MSVC++|wcout|".932"|L"こんにちは世界!"|こんにちは世界!|
233
+ |65001|MSVC++|wcout|".UTF-8"|L"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
234
+ |65001|MSVC++|wcout|""|L"😊"||
235
+ |65001|MSVC++|wcout|"C"|L"😊"||
236
+ |65001|MSVC++|wcout|".932"|L"😊"||
237
+ |65001|MSVC++|wcout|".UTF-8"|L"😊"||
238
+
239
+ ### 結果(コマンドプロンプト)
240
+ 😊が表示不可能だけで同じ
241
+
242
+ ### 現時点での考察
243
+ マルチバイト時文字列リテラルがバイナリ上シフトJISになっていることが発覚。後日考察。本当にシステムロケールUTF-8で動作するのか?

3

MSYS2-mintty上でのロケールと各種出力調査の追記

2023/12/13 03:12

投稿

dameo
dameo

スコア943

test CHANGED
@@ -47,3 +47,116 @@
47
47
  つまりC言語 locale、C++ localeに関係なくlocaleの変更がない状態ではUCRTでも同じ現象になるということのようです。
48
48
 
49
49
  今回は記述しませんがチラ見した感じだとC言語 localeのエンコーディング設定をUTF-8に変更することにより cout / wcoutに関係なく日本語の表示が可能になっていました。UCRTの挙動についてはVC++側でも未確認なので、次回調査時はそちらも合わせてlocale周りを調べてみようかと思っています。(ちまちま更新していく感じになります)
50
+
51
+ ## MSYS2-mintty上でのロケールと各種出力調査
52
+ ### 調査用コード
53
+ ```bash
54
+ for cp in "932" "65001"; do
55
+ cmd //c chcp $cp
56
+ for out in "cout" "wcout"; do
57
+ if [ "$out" == "wcout" ]; then
58
+ prefix="L"
59
+ else
60
+ prefix=""
61
+ fi
62
+ for str in "こんにちは世界!" "😊"; do
63
+ for loc in "" "C" ".932" ".UTF-8"; do
64
+ cat >hello_locale_x.cpp <<EOF
65
+ #include <iostream>
66
+ int main()
67
+ {
68
+ std::setlocale(LC_CTYPE,"$loc");
69
+ std::$out<<$prefix"$str";
70
+ return 0;
71
+ }
72
+ EOF
73
+ g++ -g -Wall -static hello_locale_x.cpp -o hello_locale_x
74
+ echo -n "|$cp|$MSYSTEM|$out|\"$loc\"|$prefix\"$str\"|"
75
+ ./hello_locale_x
76
+ echo "|"
77
+ done
78
+ done
79
+ done
80
+ echo press enter
81
+ read
82
+ done
83
+ cmd //c chcp 932
84
+ ```
85
+ ### 調査結果
86
+ |端末コードページ|MSYSTEM|出力先|ロケール(C)|リテラル(ソースUTF8)|結果|
87
+ |:--|:--:|:--:|:--|:--|:--|
88
+ |932|MINGW64|cout|""|"こんにちは世界!"||
89
+ |932|MINGW64|cout|"C"|"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
90
+ |932|MINGW64|cout|".932"|"こんにちは世界!"||
91
+ |932|MINGW64|cout|".UTF-8"|"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
92
+ |932|MINGW64|cout|""|"😊"||
93
+ |932|MINGW64|cout|"C"|"😊"|・|
94
+ |932|MINGW64|cout|".932"|"😊"||
95
+ |932|MINGW64|cout|".UTF-8"|"😊"|・|
96
+ |932|MINGW64|wcout|""|L"こんにちは世界!"||
97
+ |932|MINGW64|wcout|"C"|L"こんにちは世界!"||
98
+ |932|MINGW64|wcout|".932"|L"こんにちは世界!"||
99
+ |932|MINGW64|wcout|".UTF-8"|L"こんにちは世界!"||
100
+ |932|MINGW64|wcout|""|L"😊"||
101
+ |932|MINGW64|wcout|"C"|L"😊"||
102
+ |932|MINGW64|wcout|".932"|L"😊"||
103
+ |932|MINGW64|wcout|".UTF-8"|L"😊"||
104
+ |65001|MINGW64|cout|""|"こんにちは世界!"||
105
+ |65001|MINGW64|cout|"C"|"こんにちは世界!"|こんにちは世界!|
106
+ |65001|MINGW64|cout|".932"|"こんにちは世界!"||
107
+ |65001|MINGW64|cout|".UTF-8"|"こんにちは世界!"|こんにちは世界!|
108
+ |65001|MINGW64|cout|""|"😊"||
109
+ |65001|MINGW64|cout|"C"|"😊"|😊|
110
+ |65001|MINGW64|cout|".932"|"😊"||
111
+ |65001|MINGW64|cout|".UTF-8"|"😊"|😊|
112
+ |65001|MINGW64|wcout|""|L"こんにちは世界!"||
113
+ |65001|MINGW64|wcout|"C"|L"こんにちは世界!"||
114
+ |65001|MINGW64|wcout|".932"|L"こんにちは世界!"||
115
+ |65001|MINGW64|wcout|".UTF-8"|L"こんにちは世界!"||
116
+ |65001|MINGW64|wcout|""|L"😊"||
117
+ |65001|MINGW64|wcout|"C"|L"😊"||
118
+ |65001|MINGW64|wcout|".932"|L"😊"||
119
+ |65001|MINGW64|wcout|".UTF-8"|L"😊"||
120
+ |932|UCRT64|cout|""|"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
121
+ |932|UCRT64|cout|"C"|"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
122
+ |932|UCRT64|cout|".932"|"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
123
+ |932|UCRT64|cout|".UTF-8"|"こんにちは世界!"|こんにちは世界!|
124
+ |932|UCRT64|cout|""|"😊"|・|
125
+ |932|UCRT64|cout|"C"|"😊"|・|
126
+ |932|UCRT64|cout|".932"|"😊"|・|
127
+ |932|UCRT64|cout|".UTF-8"|"😊"|??|
128
+ |932|UCRT64|wcout|""|L"こんにちは世界!"|こんにちは世界!|
129
+ |932|UCRT64|wcout|"C"|L"こんにちは世界!"||
130
+ |932|UCRT64|wcout|".932"|L"こんにちは世界!"|こんにちは世界!|
131
+ |932|UCRT64|wcout|".UTF-8"|L"こんにちは世界!"|こんにちは世界!|
132
+ |932|UCRT64|wcout|""|L"😊"||
133
+ |932|UCRT64|wcout|"C"|L"😊"||
134
+ |932|UCRT64|wcout|".932"|L"😊"||
135
+ |932|UCRT64|wcout|".UTF-8"|L"😊"||
136
+ |65001|UCRT64|cout|""|"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
137
+ |65001|UCRT64|cout|"C"|"こんにちは世界!"|こんにちは世界!|
138
+ |65001|UCRT64|cout|".932"|"こんにちは世界!"|縺薙s縺ォ縺。縺ッ荳也阜・|
139
+ |65001|UCRT64|cout|".UTF-8"|"こんにちは世界!"|こんにちは世界!|
140
+ |65001|UCRT64|cout|""|"😊"|・|
141
+ |65001|UCRT64|cout|"C"|"😊"|😊|
142
+ |65001|UCRT64|cout|".932"|"😊"|・|
143
+ |65001|UCRT64|cout|".UTF-8"|"😊"|😊|
144
+ |65001|UCRT64|wcout|""|L"こんにちは世界!"|こんにちは世界!|
145
+ |65001|UCRT64|wcout|"C"|L"こんにちは世界!"||
146
+ |65001|UCRT64|wcout|".932"|L"こんにちは世界!"|こんにちは世界!|
147
+ |65001|UCRT64|wcout|".UTF-8"|L"こんにちは世界!"|こんにちは世界!|
148
+ |65001|UCRT64|wcout|""|L"😊"||
149
+ |65001|UCRT64|wcout|"C"|L"😊"||
150
+ |65001|UCRT64|wcout|".932"|L"😊"||
151
+ |65001|UCRT64|wcout|".UTF-8"|L"😊"||
152
+
153
+ ### 現時点での考察
154
+ mingw64/ucrt64環境では、設定ロケールを端末コードページに合わせて出力されるように見える。
155
+
156
+ mingw64では、ロケールがUTF-8("C"ロケール含む)のときだけ出力しようとするが、**実際の変換が行われない**。またwcoutの場合はロケールが何であっても出力できない。
157
+
158
+ ucrt64環境では、実際の変換も行われており"C"ロケールのときがやや特殊な変換なのと、**wcoutで絵文字が出ない**点を除き、想定どおりの動作をしている。
159
+
160
+ なので、現時点でVC++で作成したアプリと近い動きを期待する(locale設定に""を使い、システムロケールに依存した動きにする)ためには、**UCRT64でワイド文字列リテラルとwcoutを使うことが望ましい**と予想する。ただし**絵文字(他にもあるかも)は諦める必要がある**。
161
+
162
+ 次はVC++でのUCRTの動きと、コマンドプロンプト上での動作確認でしょうか。。。

2

誤記訂正

2023/12/12 23:41

投稿

dameo
dameo

スコア943

test CHANGED
@@ -32,7 +32,7 @@
32
32
  (1)(2)ともに同じ
33
33
 
34
34
  ### 試したこと
35
- (1)(2)(3)(4)(5)(6)まで同じ
35
+ (1)(2)(3)(4)(5)(6)(8)まで同じ
36
36
  (7)はちゃんとUCRT
37
37
  ```bash
38
38
  $ ldd hello

1

UCRT64で確認した結果を追記

2023/12/12 23:40

投稿

dameo
dameo

スコア943

test CHANGED
@@ -1,4 +1,7 @@
1
1
  質問への追記が文字数的に困難になってきたので、回答側に記述します。
2
+
3
+ ## wcoutへの出力についての追加情報
4
+
2
5
  とりあえずwcoutへの出力方法を以下のサイトで見つけました。
3
6
 
4
7
  http://www17.plala.or.jp/KodamaDeveloped/LetsProgramming/details_how_to_develop_japanese_application.html
@@ -17,3 +20,30 @@
17
20
  > ```
18
21
 
19
22
  引用した部分だけでなくcodecvt(C++17から非推奨)の自作や、gccの記述などもあり、まだ全部読めてませんが、仕様に対する言及も多くとても参考になりそうです。
23
+
24
+ ## UCRT64で確認した結果
25
+
26
+ 質問に記載した現象を同じ手順でUCRT64で確認した結果を簡単に記載します。
27
+
28
+ - msys/msys2-runtime 3.4.6-2
29
+ - mingw-w64-ucrt-x86_64-gcc 12.2.0-10
30
+
31
+ ### 発生している問題・エラーメッセージについて
32
+ (1)(2)ともに同じ
33
+
34
+ ### 試したこと
35
+ (1)(2)(3)(4)(5)(6)まで同じ
36
+ (7)はちゃんとUCRT
37
+ ```bash
38
+ $ ldd hello
39
+ ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7fffa15f0000)
40
+ KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7fff9fbf0000)
41
+ KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7fff9f100000)
42
+ ucrtbase.dll => /c/WINDOWS/System32/ucrtbase.dll (0x7fff9ecd0000)
43
+
44
+ $
45
+ ```
46
+
47
+ つまりC言語 locale、C++ localeに関係なくlocaleの変更がない状態ではUCRTでも同じ現象になるということのようです。
48
+
49
+ 今回は記述しませんがチラ見した感じだとC言語 localeのエンコーディング設定をUTF-8に変更することにより cout / wcoutに関係なく日本語の表示が可能になっていました。UCRTの挙動についてはVC++側でも未確認なので、次回調査時はそちらも合わせてlocale周りを調べてみようかと思っています。(ちまちま更新していく感じになります)