11
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C++(Visual Studio)でUTF-8を扱うための試行錯誤のメモ

Last updated at Posted at 2022-01-05

目的

Visual Studio(Windows)を使ってC++のコンソールアプリケーションを開発する際、

  • ソースファイルの文字コード
  • 出力するときの文字コード
  • プログラム内で扱うデータの文字コード

全てをUTF-8で扱うための試行錯誤をまとめてみることにします。

2022/01/16 :
記事の公開当初は、ISO C++ 20 標準 (/std:c++20)(u8string)を使う予定でした。
しかし、検証した結果、ISO C++ 20 標準 (/std:c++20)は使わずにISO C++ 17 標準 (/std:c++17)を使う事にしました。
なぜならば、mbrtoc8(char -> char8_t) および c8rtomb(char8_t -> char)が実装されていないからです。

環境

VisualStudio
Microsoft Visual Studio Community 2022 (3)
Version 17.0.4
VisualStudio.17.Release/17.0.4+32014.148
Microsoft .NET Framework
Version 4.8.04161

インストールされているバージョン:Community

Visual C++ 2022   00482-90000-00000-AA281
Microsoft Visual C++ 2022

Microsoft Visual C++ ウィザード   1.0
Microsoft Visual C++ ウィザード

Microsoft Visual Studio VC パッケージ   1.0
Microsoft Visual Studio VC パッケージ

...
WindowsTerminal
Windows Terminal
バージョン: 1.11.3471.0
OS
エディション	Windows 11 Pro
バージョン	21H2
インストール日	‎2021/‎10/‎24 ‎日
OS ビルド	22000.376
エクスペリエンス	Windows 機能エクスペリエンス パック 1000.22000.376.0
システムの種類	64 ビット オペレーティング システム、x64 ベース プロセッサ

WindowsのコンソールのコードページをUTF-8にする

設定->時刻と言語->言語と地域->管理用の言語設定->システムロケールの変更->ベータ: ワールドワイド言語サポートで Unicode UTF-8を使用にチェックを入れます。
こうする事でコンソールのデフォルトコードページがUTF-8になるようです。

もしくは、main関数の先頭あたりに以下のコードを記述すれば、出力コンソールのコードページがUTF-8になります。
そして、setvbuf()stdoutにバッファを設定します。
文字列がUTF-8の場合は、バッファを設定しないと正常に出力されない事があるらしいです。
また、バッファを設定するとprintf_s()の後などでfflush(stdout)を用いてバッファをフラッシュする必要が出てくることがあります。

#include <Windows.h>
#include <stdio.h>

int main() {
  SetConsoleOutputCP(CP_UTF8);
  setvbuf(stdout, nullptr, _IOFBF, 1024);
  return 0;
}

.editorconfigを用意する

.editorconfigを使うとソリューション毎に文字コードを制御できます。
ほぼ全てのソリューションに対して設定したい場合は、Visual Studioのデフォルト設定の場合は、C:\Users\<UserName>\source\repos.editorconfigを作成します。
その内容は、以下のようにします。

.editorconfig
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2
```

# Visual Studioのテキストエディターの設定

ツール -> オプション -> テキストエディター -> 全般 -> `シグネチャなしの UTF-8エンコードを自動検出`をチェック
これでソースファイルが`UTF-8`でも扱えるようになります。

# Visual Studioのプロジェクトテンプレートを作成する

Visual Studioで`新しいプロジェクトの作成`を実行し、`空のプロジェクト`を作成します。

1. デバッグ-> <SolutionName>のデバッグプロパティを開く
2. 構成 -> `全ての構成`に変更する
3. **必要に応じて** 構成プロパティ-> 全般 -> C++ 言語標準 -> `ISO C++ 17 標準 (/std:c++17)`に変更する 
4. 構成プロパティ-> 詳細 -> 文字セット -> `Unicode 文字セットを使用する`に変更する
5. 構成プロパティ-> リンカー -> コマンド ライン -> 追加のオプションに`/utf-8`を追加する

デフォルトのソースファイルやヘッダーファイルが要らない場合は、このままプロジェクトテンプレートを作成します。
この記事では、`UTF-8`が有効になっているか確認の意味を込めて以下のファイルをプロジェクトに追加してからテンプレートを作成することにします。

1. ソリューション エクスプローラー -> ソースファイルを右クリック
2. 追加 -> 新しい項目 -> C++ ファイル

```cpp:main.cpp
#include <Windows.h>
#include <vector>
#include <string>

int main()
{
  std::string u8str = u8"尾も白い猫";
  std::string str = "尾も黒い猫";

  printf_s("%d\n", GetConsoleOutputCP());
  printf_s("start\n");
  printf_s(u8"動物: %s\n", u8str.data());
  printf_s("動物: %s\n", str.data());
  printf_s("end\n");

  return 0;
}
```

最後にプロジェクトテンプレートを保存します。

- プロジェクト-> テンプレートのエクスポート

# 動作確認

作成したプロジェクトテンプレートを用いて新しいプロジェクトを作成すれば、ソースファイルと出力と扱うデータ全て`UTF-8`になっているかと思います。

標準ライブラリだけで`UTF-8`を楽に扱えるようになってもらいたいものです。
11
14
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?