SJISからUTF-8への文字コード変換

最近、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を付加していません。


Tagged:

Leave a comment

メールアドレスが公開されることはありません。

CAPTCHA


*