ページ 11

C++でUTF-8

Posted: 2017年4月01日(土) 03:21
by 酢飯
VS2017CommunityでUTF-8の文字列を変数に入れ、中身を確認したところ、
<文字列中に無効な文字があります>
となってしまい、文字として認識してくれません。

文字列として認識させるにはどのようにすればよいのでしょうか?
よろしくお願いします。

コード:

#include <string>

int main() {
    char buf[] = u8"あいうえお";
    std::string str(u8"あいうえお");
    return 0;
}

Re: C++でUTF-8

Posted: 2017年4月01日(土) 19:17
by あたっしゅ
 Embarcadero® C++Builder 10.1 Berlin バージョン 24.0.25048.9432 で似たプログラムをやってみたところ、

>[bcc32 エラー] File1.cpp(15): E2451 未定義のシンボル u8

と出ました。
 つまり、私の使用したコンパイラも、貴方の使用しているコンパイラも、古くて、C++11 規格に対応していないのでは ?
 VS2017 だと、他のスレッドを読んだ限りでは、「ソースが UTF-8」と指定してやれば、u8 抜きで UTF-8 なリテラルが使えるようですが...

Re: C++でUTF-8

Posted: 2017年4月02日(日) 17:37
by ISLe
Visual StudioのIDEが文字として認識するのは、ワイド文字(wchar_t)かANSI文字(char)です。

std::stringはANSI文字対応なので、ANSI文字列に変換する必要があります。

文字コードの変換に言語レベルでの標準は無く、下記はWin32 APIを使う場合の例です。

コード:

#include <string>
#include <iostream>
#include <windows.h>

int main()
{
	char buf_utf8[] = u8"あいうえお";
	wchar_t buf_wc[256];// = L"あいうえお";
	char buf_ansi[256];// = "あいうえお";

	// UTF-8文字列からワイド文字列へ変換
	MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buf_utf8, -1, buf_wc, 256);
	// ワイド文字列からANSI(CP932)文字列へ変換
	WideCharToMultiByte(CP_ACP, 0, buf_wc, -1, buf_ansi, 256, nullptr, nullptr);

	std::string str(buf_ansi);
	std::cout << str << std::endl;
	return 0;
}

Re: C++でUTF-8

Posted: 2017年4月03日(月) 00:59
by YuO
酢飯 さんが書きました:VS2017CommunityでUTF-8の文字列を変数に入れ、中身を確認したところ、
<文字列中に無効な文字があります>
となってしまい、文字として認識してくれません。
ソースコード自体の文字コードは何ですか。

Visual C++のコンパイラは,Windowsのコードページの文字コードとソースコードの文字コードが一致するのであればそのままコンパイルできますが,
そうでないのであれば,/source-charsetのオプションを追加しておく必要があります。
なお,このコンパイラオプションはIDEサポートがないので,上記のリンク先にあるように,直接[追加のオプション]として記述する必要があります。
ref) http://dixq.net/forum/viewtopic.php?f=3&t=17924#p137736
オフトピック
#pragma execution_character_setに相当する,#pragma source_character_setがあれば便利だと思いますが,残念ながら実装されていません。
まぁ,ソースコード中二角場合だと,先頭に書かないといけなかったり(文字コードが途中から変更されるとか混乱の極みなので),ASCII互換必須(UTF-16とかは対応できない),IDEが対応しないといけない(読み込み・保存)などの問題点はありますが。