概要

S-JISのテキストファイルをHTMLのpreタグに対応した書式に変換しUTF-8で保存します。
テキストファイルは本プログラムにファイルをドラックドロップして指定します。
ドラッグドロップ後にOKボタンをクリックすると変換されます。
複数ファイルの同時変換に対応します。変換後のファイルは元のファイルと同じフォルダーに保存され、ファイル名に_utf8が付加され作成されます。拡張子はtxtとなります。したがって、複数のファイルで拡張子が異なってファイル名が同じ場合、区別がつかなくなります。
元のファイルは変更されません。

変更履歴

2014.04.24 初版
2014.05.07 exeファイル実行前にドラッグ&ドロップした場合のファイル名にダブルコーテーションが付加される場合に対応

テスト環境

コンパイラ

Visual C++ 2008/2013 Express 32/64bit UNICODE

実行環境

Windows XP Professional Service Pack 3 32bit(Virtual Box上の仮想マシーン)
Windows 7 Enterprise Service Pack 1 64bit

動作例

変換元ファイル(src.cpp)S-JIS

本プログラムを起動した状態

変換後ファイル(src_utf8.cpp)UTF8

プログラムソースの概要

gpretxt.cpp

_tWinMain

_tWinMain関数よりダイアログボックスを表示します。

DlgProc1

ダイアログの初期化時にDlgProc1関数がWM_INITDIALOGメッセージが発生し、DragAcceptFiles APIを読み出すことによりファイルのドラッグ&ドラッグの受付を許可します。
本プログラム起動時に引数があった場合は、リストボックスにその内容を設定します。
ファイルがドラッグ&ドラッグされるとDlgProc1関数にWM_DROPFILESメッセージが発生するので、DragQueryFile関数で最初にファイルの個数を取得し、次にファイル名を取得します。
取得されたファイル名は、リストボックスに登録します。
ボタンがクリックされると、DlgProc1関数にWM_COMMANDメッセージが発生するので、OKボタンのメッセージの場合、リストボックスの内容を取得し変換元のファイル名とします。
変換後のファイル名は、PathRemoveExtension APIでファイル名から拡張子を取り除き、代わりに_utf8.txtを付加してファイル名とします。
変換前、変換後のファイル名が取得できたなら、pretxt関数でpreタグに対応した書式に変換します。

pretxt

fgets関数でファイルを呼び出し、MultiByteToWideChar関数でS-JISをUTF16に変換します。
文字列をpreタグに対応した書式に変換します。
_fputtsでUTF16の文字列を出力すると、_tfopen_sを呼び出すときにエンコードをUTF-8で指定しているので、UTF-8に変換されてファイルに書き込まれます。

ソースコード

gpretxt.cpp

// SHIFT-JISファイルをpreタグに対応したUTF-8テキストファイルに変換
// ファイルの指定はドラッグ&ドラッグによる
// VC2008/VC2013 Express  32/64bit Unicode
// 2014/05/05

#include <windows.h>
#include <commctrl.h> 
#include <stdio.h>
#include <tchar.h>
#include <shlobj.h>
#include <shlwapi.h>
#include "resource.h"

#pragma comment(lib,"shlwapi.lib")


#define BUF_MAX 1024


int pretxt(TCHAR* dtc_file,TCHAR* src_file);

LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);

TCHAR* file=0;

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInst,TCHAR* lpszCmdLine, int nCmdShow){
	TCHAR f[MAX_PATH];
	if(lpszCmdLine[0]){
		if(lpszCmdLine[0]==_T('\"')){
			_tcscpy_s(f,sizeof(f)/sizeof(TCHAR),lpszCmdLine+1);
			f[ _tcslen(f) -1]=_T('\0');
			file=f;
		}else
			file=lpszCmdLine;
	}
	DialogBox(hInstance, TEXT("DLG1"), 0, (DLGPROC)DlgProc1);
	return 0;
}

//	ダイアログボックスのプロシージャー

LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
	TCHAR buf[MAX_PATH];
	HDROP hDrop;
	UINT fmax;
	int	i;
	switch (msg) {
		case WM_INITDIALOG:
			DragAcceptFiles(hDlg, TRUE);
			if(file)
				SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) , LB_ADDSTRING , 0 , (LPARAM)file);
			return TRUE;
		case WM_DROPFILES:
			hDrop = (HDROP)wParam;
			fmax = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);
			for(i = 0; i < (int)fmax; i++) {
				DragQueryFile(hDrop, i, buf, sizeof(buf)/sizeof(TCHAR));
				SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) , LB_ADDSTRING , 0 , (LPARAM)buf);
			}
			DragFinish(hDrop);
			break;
		case WM_COMMAND:
			switch (LOWORD(wParam)) {
				case IDOK:
					fmax=(UINT)SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) ,LB_GETCOUNT,0,0);
					for(i = 0; i < (int)fmax; i++){
						SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) ,LB_GETTEXT,i,(LPARAM)buf);
						TCHAR dtc_file[MAX_PATH];
						_tcscpy_s(dtc_file,sizeof(dtc_file)/sizeof(TCHAR),buf);
						PathRemoveExtension(dtc_file);	//拡張子を取り除く
						_tcscat_s(dtc_file,sizeof(dtc_file)/sizeof(TCHAR),_TEXT("_utf8.txt"));
						pretxt(dtc_file,buf);
					}
					EndDialog(hDlg, TRUE);
					return TRUE;
				case IDCANCEL:
					EndDialog(hDlg,FALSE);
					return FALSE;
				default:
					return FALSE;
			}
			default:
				return FALSE;
	}
	return TRUE;
}

//	src_fileで示されるS-JISファイルを開きHTMLのpreタグに合わせた書式に変換しUTF-8で保存する

int pretxt(TCHAR* dtc_file,TCHAR* src_file){
	TCHAR utf16[BUF_MAX*2];
	TCHAR dtc[BUF_MAX*2];
	FILE* src_fp;
	FILE* dtc_fp;

	int f=0;

	if(_tfopen_s(&src_fp,src_file,_TEXT("r"))){
		return -1;

	}
	if(_tfopen_s(&dtc_fp,dtc_file,_TEXT("w, ccs=UTF-8"))){
		fclose(src_fp);
		return -1;
	}

	char sjis_buf[BUF_MAX*2];
	while( fgets(sjis_buf,BUF_MAX*2,src_fp) != NULL ){
		MultiByteToWideChar(932,0,sjis_buf,sizeof(sjis_buf),utf16,sizeof(utf16)/sizeof(TCHAR));
		TCHAR* src_p=utf16;
		TCHAR* dtc_p=dtc;
		while(*src_p){
			switch(*src_p){
			case _T('<'):
				*dtc_p++=_T('&');
				*dtc_p++=_T('l');
				*dtc_p++=_T('t');
				*dtc_p++=_T(';');
				break;
			case _T('>'):
				*dtc_p++=_T('&');
				*dtc_p++=_T('g');
				*dtc_p++=_T('t');
				*dtc_p++=_T(';');
				break;
			case _T('&'):
				*dtc_p++=_T('&');
				*dtc_p++=_T('a');
				*dtc_p++=_T('m');
				*dtc_p++=_T('p');
				*dtc_p++=_T(';');
				break;
			case _T('\"'):
				*dtc_p++=_T('&');
				*dtc_p++=_T('q');
				*dtc_p++=_T('u');
				*dtc_p++=_T('o');
				*dtc_p++=_T('t');
				*dtc_p++=_T(';');
				break;
			default:
				*dtc_p++=*src_p;
			}
			++src_p;
		}
		*dtc_p=_T('\0');
		_fputts(dtc,dtc_fp);
	}

	fclose(src_fp);
	fclose(dtc_fp);
	return 0;
}

resource.h

#define IDC_LISTBOX1 2001

resource.rc

#include <windows.h>
#include "resource.h"


DLG1 DIALOG DISCARDABLE  0, 0, 174, 185
STYLE DS_MODALFRAME | WS_POPUP
CAPTION "ファイル名"
FONT 9, "MS Pゴシック"
BEGIN
	CONTROL "ListBox", IDC_LISTBOX1, "LISTBOX", WS_CHILD | WS_VISIBLE | WS_VSCROLL | LBS_DISABLENOSCROLL , 7, 26, 160, 128
	LTEXT			"ここへファイルをドラッグドロップしてください",-1,7,7,168,10
	DEFPUSHBUTTON	"OK",IDOK,62,168,50,14
END

実行ファイルとソースファイルのダウンロード