最近、Windows標準のShift-JISから、Web標準となっている(?)UTF-8への文字コード変換が必要な場合がちらほら出てきている。
マルチプラットフォームでデータをやり取りする場合なんかでもUTF-8が結構使われていたりする。
こういうコード変換なんかは、テキストエディタ等を使えば、簡単に変換できる。
最近ではメモ帳でもUTF-8保存ができるようになったし。
でも、このコード変換が100個、1000個、と数が増えてくると手作業は無理。
そんな訳で、VC++(非.NET)でSJISからUTF-8に変換するプログラムを作ってみることにした。
# バッチで利用したいという理由もあったんで。
しかし、SJISからUTF-8に直接変換するようなWin32APIは用意されていないことに気付いた。
C#やVB.NETならきっと一発で変換できるんだろうけど(多分)。
調べてみると、シフトJISからUTF-8に変換するためには、一回Unicodeに変換させる必要があることが分かった。
あぁ面倒。
まず、MultiByteToWideCharを使用し、SJISからUnicodeへ。
次に、WideCharToMultiByteを使用し、UnicodeからUTF-8へ。
出来上がったプログラムソースは以下のとおり。
#include "stdafx.h"
#include "Windows.h"
#define NUM_OF_LINE_CHARS 200
int _tmain(int argc, _TCHAR* argv[])
{
FILE *targetFile,*tmpFile;
wchar_t wszTmpFile[_MAX_PATH];
wchar_t wszBuf[NUM_OF_LINE_CHARS];
char zsLineIn[NUM_OF_LINE_CHARS];
char zsLineOut[NUM_OF_LINE_CHARS * 2];
wsprintf(wszTmpFile,_TEXT("%s.tmp"),argv[1]);
memset(zsLineOut,0x00,NUM_OF_LINE_CHARS * 2);
if(argc!=2){
printf_s("\nusage: %S ファイル名\n",argv[0]);
return -1;
}
// 一時ファイルをオープン
if( _wfopen_s( &tmpFile, wszTmpFile, L"w" ) != 0 )
{
printf_s(
"%S:一時ファイル作成エラー(%S)\n",
argv[0],
wszTmpFile);
return -1;
}
// 指定したファイルをオープン
if( _wfopen_s( &targetFile, argv[1], L"r" ) == 0 )
{
// EOFまで繰り返し
while(!feof(targetFile)){
// 行単位で読み込み
if(fgets(zsLineIn,NUM_OF_LINE_CHARS,targetFile)!=NULL)
{
// SJIS → Unicode
if(MultiByteToWideChar(
CP_ACP,
0,
(const char *)zsLineIn,
-1,
wszBuf,
NUM_OF_LINE_CHARS) == 0)
{
printf_s(
"%S:変換エラー(MultiByteToWideChar)\n",
argv[0]);
return -1;
}
// Unicode → UTF8
if(WideCharToMultiByte(
CP_UTF8,
0,
wszBuf,
-1,
(char *)zsLineOut,
NUM_OF_LINE_CHARS,
NULL,
NULL) == 0)
{
printf_s(
"%S:変換エラー(WideCharToMultiByte)\n",
argv[0]);
return -1;
}
fputs(zsLineOut,tmpFile);
}
}
_fcloseall();
// ファイル置き換え
_wremove(argv[1]);
_wrename(wszTmpFile,argv[1]);
}else{
printf_s(
"%S:ファイルオープンエラー(%S)\n",
argv[0],
argv[1]);
return -1;
}
return 0;
}
出来上がったexeファイルはコマンドプロンプトより実行する。
第一引数に、コード変換させたいSJISファイル名を指定する。
第一引数に指定したファイルは、UTF-8ファイルに書き換えられる。
※このプログラムで出力するUTF-8ファイルは、BOMを付加していません。






