合計 昨日 今日

utf16beの読み込み方法

[このトピックは解決済みです]

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: 駆け出し
[URL]
上級者(19,485 ポイント)
Date: 2017年5月15日(月) 22:10
No: 1
(OFFLINE)

 utf16beの読み込み方法

こんにちは。テキストエディタを作成しているのですが、UTF-16BEのファイルを読み込めず右往左往しています。UTF-16LE、UTF-8は読み込めています。
_wfopen_sにはMSDNを見る限りutf16-beを読み込めないようなのです。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#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 バイト) ダウンロード数: 8 回

Name: keito94
[URL]
上級者(17,945 ポイント)
Date: 2017年5月16日(火) 18:45
No: 2
(OFFLINE)

 Re: utf16beの読み込み方法

どうやら、C言語の標準機能で、UTF-16BEを読み込もうと努力しているわけですね。
何かのライブラリが必要だと思いますよ。
知識不足注意。
只今デバッグトレーニング中。
目の前の問題に夢中でアドバイスを聞かないのかもしれません。
時折問題を投げ捨てて勝手に解決させてしまうかもしれませんが、予めご了承ください。
(僕自身は至って真剣です。)

Name: inemaru
[URL]
上級者(15,871 ポイント)
Date: 2017年5月16日(火) 22:25
No: 3
(OFFLINE)

 Re: utf16beの読み込み方法

標準ライブラリのcodecvt_utf16を使用する方法がありますが、どうですか?
下記の実装は、BOM付utf16BEを表示するサンプルです。

環境:VS2013/Unicodeプロジェクト
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <windows.h>
#include <locale>
#include <fstream>
#include <string>
#include <codecvt>
 
using namespace std;
 
std::wstring GetString_UTF16BE(const char* filePath)
{
    wifstream ifs(filePath);
    if (!ifs) {
        // 読み込み失敗
        return L"";
    }
    ifs.imbue(locale(locale::empty(), new codecvt_utf16<wchar_t, 0x10ffff, consume_header>));
    return wstring(istreambuf_iterator<wchar_t>(ifs), istreambuf_iterator<wchar_t>());
}
 
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    // ロケールをデフォルトに設定
    locale::global(locale(""));
    setlocale(LC_ALL, locale().c_str());
 
    // utf16be表示
    MessageBoxW(nullptr, GetString_UTF16BE("test-utf16be.txt").c_str(), L"", MB_OK);
 
    return 0;
}

Name: 駆け出し
[URL]
上級者(19,485 ポイント)
Date: 2017年5月17日(水) 13:53
No: 4
(OFFLINE)

 Re: utf16beの読み込み方法

ありがとうございます。C++ほとんど触ってないので、試行錯誤しながらやっていきたいと思います!

Name: 駆け出し
[URL]
上級者(19,485 ポイント)
Date: 2017年5月21日(日) 13:37
No: 5
(OFFLINE)

 Re: utf16beの読み込み方法

[解決!]

解決つけ忘れてました。


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[6人]