首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何读取UCS-2文件?

如何读取UCS-2文件?
EN

Stack Overflow用户
提问于 2012-07-25 13:51:12
回答 2查看 5.5K关注 0票数 5

我正在写一个程序,以获取以*.rc文件编码的UCS-2小端的信息。

代码语言:javascript
复制
int _tmain(int argc, _TCHAR* argv[]) {
  wstring csvLine(wstring sLine);
  wifstream fin("en.rc");
  wofstream fout("table.csv");
  wofstream fout_rm("temp.txt");
  wstring sLine;
  fout << "en\n";
  while(getline(fin,sLine)) {
    if (sLine.find(L"IDS") == -1)
      fout_rm << sLine << endl;
    else
      fout << csvLine(sLine);
  }
  fout << flush;
  system("pause");
  return 0;
}

"en.rc“的第一行是#include <windows.h>,但sLine显示如下:

代码语言:javascript
复制
[0]     255 L'ÿ'
[1]     254 L'þ'
[2]     35  L'#'
[3]     0
[4]     105 L'i'
[5]     0
[6]     110 L'n'
[7]     0
[8]     99  L'c'
.       .
.       .
.       .

这个程序可以正确地运行于UTF-8。如何对UCS-2执行此操作?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-26 01:34:36

宽流使用宽流缓冲区来访问文件。宽流缓冲区从文件中读取字节,并使用其codecvt方面将这些字节转换为宽字符。默认的codecvt facet是std::codecvt<wchar_t, char ,std::mbstate_t>,它在wchar_tchar的原生字符集之间进行转换(例如,像mbstowcs(一样)。

您没有使用原生字符集,所以您需要的是一个编解码器facet,它将UCS-2读取为多字节序列并将其转换为宽字符。

代码语言:javascript
复制
#include <fstream>
#include <string>
#include <codecvt>
#include <iostream>

int main(int argc, char *argv[])
{
    wifstream fin("en.rc", std::ios::binary); // You need to open the file in binary mode

    // Imbue the file stream with a codecvt facet that uses UTF-16 as the external multibyte encoding
    fin.imbue(std::locale(fin.getloc(),
              new std::codecvt_utf16<wchar_t, 0xffff, consume_header>));

    // ^ We set 0xFFFF as the maxcode because that's the largest that will fit in a single wchar_t
    //   We use consume_header to detect and use the UTF-16 'BOM'

    // The following is not really the correct way to write Unicode output, but it's easy
    std::wstring sLine;
    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> convert;
    while (getline(fin, sLine))
    {
        std::cout << convert.to_bytes(sLine) << '\n';
    }
}

注意,这里有一个关于UTF-16的问题。wchar_t的目的是让一个wchar_t代表一个码点。然而,Windows使用的是UTF-16,它将一些代码点表示为两个wchar_t,这意味着标准的API在Windows上不能很好地工作。

这里的结果是,当文件包含代理项对时,codecvt_utf16将读取该对,将其转换为大于16位的单个码点值,并且必须将该值截断为16位以将其粘贴到wchar_t中。这意味着这段代码实际上仅限于UCS-2。我已经将maxcode模板参数设置为0xFFFF以反映这一点。

wchar_t还有许多其他问题,您可能希望完全避免它:What's “wrong” with C++ wchar_t?

票数 10
EN

Stack Overflow用户

发布于 2020-11-24 16:56:54

代码语言:javascript
复制
#include <filesystem>
namespace fs = std::filesystem;

    FILE* f = _wfopen(L"myfile.txt", L"rb");
    auto file_size = fs::file_size(filename);
std::wstring buf;       
buf.resize((size_t)file_size / sizeof(decltype(buf)::value_type));// buf in my code is a template object, so I use decltype(buf) to decide its type.
    fread(&buf[0], 1, 2, f); // escape UCS2 BOM
    fread(&buf[0], 1, file_size, f);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11643500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档