VisualStudio と MFC を使用して C++ で (たまに) プログラミングしています。fopen と fprintf でファイルを書き込みます。ファイルは UTF8 でエンコードする必要があります。これを行う可能性はありますか?何を試しても、ファイルは 2 バイトの Unicode または ISO-8859-2 (latin2) でエンコードされています。
グラネブリッジ
fprintfを使用するだけの場合は、ロケールを設定したり、ファイルに特別なモードを設定したりする必要はありません。UTF-8でエンコードされた文字列を使用するだけです。
#include <cstdio>
#include <codecvt>
int main() {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t> convert;
std::string utf8_string = convert.to_bytes(L"кошка 日本国");
if(FILE *f = fopen("tmp","w"))
fprintf(f,"%s\n",utf8_string.c_str());
}
プログラムを署名付きのUTF-8またはUTF-16として保存します(つまり、署名なしのUTF-8を使用しないでください。そうしないと、VSは正しい文字列リテラルを生成しません)。プログラムによって作成されたファイルには、その文字列のUTF-8バージョンが含まれます。または、次のことができます。
int main() {
if(FILE *f = fopen("tmp","w"))
fprintf(f,"%s\n","кошка 日本国");
}
この場合、ファイルを署名なしでUTF-8として保存する必要があります。これは、ソースエンコーディングが実行エンコーディングと同じであるとコンパイラに認識させたいためです...これは、コンパイラのIMOに依存するちょっとしたハックです。壊れた動作。
ファイルに狭い文字を書き込むための他のAPIでも基本的に同じことを行うことができますが、これらのメソッドはいずれもWindowsコンソールにUTF-8を書き込むためには機能しないことに注意してください。Cランタイムやコンソールが少し壊れているため、SetConsoleOutputCP(65001)を実行してから、puts
さまざまな関数の1つを使用することによってのみ、UTF-8をコンソールに直接書き込むことができます。
幅の狭い文字の代わりに幅の広い文字を使用したい場合は、ロケールベースのメソッドとファイル記述子の設定モードが役立ちます。
#include <cstdio>
#include <fcntl.h>
#include <io.h>
int main() {
if(FILE *f = fopen("tmp","w")) {
_setmode(_fileno(f), _O_U8TEXT);
fwprintf(f,L"%s\n",L"кошка 日本国");
}
}
#include <fstream>
#include <codecvt>
int main() {
if(auto f = std::wofstream("tmp")) {
f.imbue(std::locale(std::locale(),
new std::codecvt_utf8_utf16<wchar_t>)); // assumes wchar_t is UTF-16
f << L"кошка 日本国\n";
}
}
はい。ただし、Visual Studio 2005 以降が必要です。次に、パラメーターを指定して fopen を呼び出すことができます。
LPCTSTR strText = "абв";
FILE *f = fopen(pszFilePath, "w,ccs=UTF-8");
_ftprintf(f, _T("%s"), (LPCTSTR) strText);
これは Microsoft 拡張機能であることを覚えておいてください。おそらく gcc やその他のコンパイラでは動作しません。
理論的には、UTF-8 を外部エンコーディングとして使用するロケールを設定する必要があります。私の理解-私はWindowsプログラマーではありません-Windowsにはそのようなロケールがないため、実装固有の手段または非標準ライブラリに頼る必要があります(Daveのコメントからのリンク)。