#1
by 駆け出し » 8年前
こんにちは。テキストエディタを作成しているのですが、UTF-16BEのファイルを読み込めず右往左往しています。UTF-16LE、UTF-8は読み込めています。
_wfopen_sにはMSDNを見る限りutf16-beを読み込めないようなのです。
コード:
#include <Windows.h>
#include <stdio.h>
#include <Shlwapi.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#pragma comment(lib,"Shlwapi.lib")
//BOMを内部で識別するためのマクロ
#define BOM_UTF_8 (0x01) //utf-8
#define BOM_UTF_16 (0x02) //utf-16
#define BOM_UTF_32 (0x04) //utf-32
#define BOM_UTF_7 (0x08) //utf-7
#define BOM_BE (0x10) //be
#define BOM_LE (0x20) //le
//BOM
//[0]...BOMのサイズ、[1]...BOM識別用のマクロ、[2]-[6]BOM
const unsigned char BOM[6][6] = {
{ 3,BOM_UTF_8, 0xef,0xbb,0xbf },
{ 2,BOM_UTF_16|BOM_BE, 0xfe,0xff },
{ 2,BOM_UTF_16|BOM_LE, 0xff,0xfe },
{ 4,BOM_UTF_32|BOM_BE, 0x00,0x00,0xfe,0xff },
{ 4,BOM_UTF_32|BOM_LE,0xff, 0xfe, 0x00, 0x00 },
{ 3,BOM_UTF_7, 0x2b,0x2f,0x76 }
};
int getBOM(LPCWSTR lpFile,int *bomsize)
{
FILE *fp;
char Buf[4];
_wfopen_s(&fp, lpFile, L"rb");
if (!fp)
return 0;
fread(Buf, 4, 1, fp);
for (int i = 0; i < 6; i++)
{
if (!memcmp(BOM[i] + 2, Buf, BOM[i][0]))
{
*bomsize = BOM[i][0];
return BOM[i][1];
}
}
//BOMなし
*bomsize = 0;
return 0;
}
size_t GetFileSizeEx(LPCWSTR lpFileName)
{
struct _stat stbuf;
int fd;
_wsopen_s(&fd, lpFileName, _O_BINARY,
_SH_DENYWR, _S_IREAD);
if (fd == -1) {
return INVALID_VALUE; //0xfffffff...
}
if (_fstat(fd, &stbuf) == -1) {
/* エラー処理 */
return INVALID_VALUE;
}
_close(fd);
return stbuf.st_size;
}
size_t EDMultiByteToWideChar(LPCSTR lpszMultiByte, LPWSTR *WideCharTemp)
{
size_t len;
WCHAR *Buffer;
len = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
lpszMultiByte,
-1,
NULL,
0
);
Buffer = (WCHAR*)malloc(len * sizeof(WCHAR));
if (!Buffer)
{
*WideCharTemp = NULL;
return FALSE;
}
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
lpszMultiByte,
-1,
Buffer,
(int)(len)
);
*WideCharTemp = Buffer;
return len;
}
int edLoadPlainText(LPCWSTR lpFile,WCHAR **loadedText,const int forceBOM = 0)
{
FILE *fp;
int bomsize;
size_t size;
void *loaded;
int filebom;
WCHAR mode[32] = { 0 };
wcscpy_s(mode, L"rb");
filebom = getBOM(lpFile, &bomsize);
if(forceBOM)
filebom = forceBOM;
if ((size = GetFileSizeEx(lpFile)) == INVALID_VALUE)
return FALSE;
if ((filebom & BOM_UTF_8))
wcscat_s(mode, L", ccs=UTF-8");
else if ((filebom & BOM_UTF_16) && (filebom & BOM_LE))
wcscat_s(mode, L", ccs=UTF-16LE");
/* else if ((filebom & BOM_UTF_16) && (filebom & BOM_BE))
wcscat_s(mode, L", ccs=UNICODE");*/
_wfopen_s(&fp, lpFile, mode);
if (!fp)
return FALSE;
if ((loaded = calloc(1,size + 2/*NULL*/)) == NULL)
{
fclose(fp);
return FALSE;
}
fread(loaded, size, 1, fp);
//もしBOMがUTF-16を指している場合は
if ((filebom & BOM_UTF_16))
{
*loadedText = (WCHAR*)loaded + bomsize / sizeof(WCHAR);
fclose(fp);
return TRUE;
}
//utf-8なら変換して返す
EDMultiByteToWideChar((LPCSTR)loaded + bomsize, loadedText);
fclose(fp);
return TRUE;
}
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
//テスト
WCHAR *t1, *t2, *t3, *t4;
edLoadPlainText(L"test-utf-8.txt", &t1);
edLoadPlainText(L"test-utf16le.txt", &t2);
edLoadPlainText(L"test-.txt", &t3);
edLoadPlainText(L"test-utf16be.txt", &t4);
}
- 添付ファイル
-
- test-utf16be.zip
- メモ帳で作成したものになります
- (523 バイト) ダウンロード数: 158 回
こんにちは。テキストエディタを作成しているのですが、UTF-16BEのファイルを読み込めず右往左往しています。UTF-16LE、UTF-8は読み込めています。
_wfopen_sにはMSDNを見る限りutf16-beを読み込めないようなのです。
[code]
#include <Windows.h>
#include <stdio.h>
#include <Shlwapi.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#pragma comment(lib,"Shlwapi.lib")
//BOMを内部で識別するためのマクロ
#define BOM_UTF_8 (0x01) //utf-8
#define BOM_UTF_16 (0x02) //utf-16
#define BOM_UTF_32 (0x04) //utf-32
#define BOM_UTF_7 (0x08) //utf-7
#define BOM_BE (0x10) //be
#define BOM_LE (0x20) //le
//BOM
//[0]...BOMのサイズ、[1]...BOM識別用のマクロ、[2]-[6]BOM
const unsigned char BOM[6][6] = {
{ 3,BOM_UTF_8, 0xef,0xbb,0xbf },
{ 2,BOM_UTF_16|BOM_BE, 0xfe,0xff },
{ 2,BOM_UTF_16|BOM_LE, 0xff,0xfe },
{ 4,BOM_UTF_32|BOM_BE, 0x00,0x00,0xfe,0xff },
{ 4,BOM_UTF_32|BOM_LE,0xff, 0xfe, 0x00, 0x00 },
{ 3,BOM_UTF_7, 0x2b,0x2f,0x76 }
};
int getBOM(LPCWSTR lpFile,int *bomsize)
{
FILE *fp;
char Buf[4];
_wfopen_s(&fp, lpFile, L"rb");
if (!fp)
return 0;
fread(Buf, 4, 1, fp);
for (int i = 0; i < 6; i++)
{
if (!memcmp(BOM[i] + 2, Buf, BOM[i][0]))
{
*bomsize = BOM[i][0];
return BOM[i][1];
}
}
//BOMなし
*bomsize = 0;
return 0;
}
size_t GetFileSizeEx(LPCWSTR lpFileName)
{
struct _stat stbuf;
int fd;
_wsopen_s(&fd, lpFileName, _O_BINARY,
_SH_DENYWR, _S_IREAD);
if (fd == -1) {
return INVALID_VALUE; //0xfffffff...
}
if (_fstat(fd, &stbuf) == -1) {
/* エラー処理 */
return INVALID_VALUE;
}
_close(fd);
return stbuf.st_size;
}
size_t EDMultiByteToWideChar(LPCSTR lpszMultiByte, LPWSTR *WideCharTemp)
{
size_t len;
WCHAR *Buffer;
len = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
lpszMultiByte,
-1,
NULL,
0
);
Buffer = (WCHAR*)malloc(len * sizeof(WCHAR));
if (!Buffer)
{
*WideCharTemp = NULL;
return FALSE;
}
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
lpszMultiByte,
-1,
Buffer,
(int)(len)
);
*WideCharTemp = Buffer;
return len;
}
int edLoadPlainText(LPCWSTR lpFile,WCHAR **loadedText,const int forceBOM = 0)
{
FILE *fp;
int bomsize;
size_t size;
void *loaded;
int filebom;
WCHAR mode[32] = { 0 };
wcscpy_s(mode, L"rb");
filebom = getBOM(lpFile, &bomsize);
if(forceBOM)
filebom = forceBOM;
if ((size = GetFileSizeEx(lpFile)) == INVALID_VALUE)
return FALSE;
if ((filebom & BOM_UTF_8))
wcscat_s(mode, L", ccs=UTF-8");
else if ((filebom & BOM_UTF_16) && (filebom & BOM_LE))
wcscat_s(mode, L", ccs=UTF-16LE");
/* else if ((filebom & BOM_UTF_16) && (filebom & BOM_BE))
wcscat_s(mode, L", ccs=UNICODE");*/
_wfopen_s(&fp, lpFile, mode);
if (!fp)
return FALSE;
if ((loaded = calloc(1,size + 2/*NULL*/)) == NULL)
{
fclose(fp);
return FALSE;
}
fread(loaded, size, 1, fp);
//もしBOMがUTF-16を指している場合は
if ((filebom & BOM_UTF_16))
{
*loadedText = (WCHAR*)loaded + bomsize / sizeof(WCHAR);
fclose(fp);
return TRUE;
}
//utf-8なら変換して返す
EDMultiByteToWideChar((LPCSTR)loaded + bomsize, loadedText);
fclose(fp);
return TRUE;
}
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
//テスト
WCHAR *t1, *t2, *t3, *t4;
edLoadPlainText(L"test-utf-8.txt", &t1);
edLoadPlainText(L"test-utf16le.txt", &t2);
edLoadPlainText(L"test-.txt", &t3);
edLoadPlainText(L"test-utf16be.txt", &t4);
}
[/code]