0

我正在读取一个 UTF-8 编码的 unicode 文本文件,并将其输出到控制台,但显示的字符与我用来创建文件的文本编辑器中的字符不同。这是我的代码:

#define UNICODE

#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>

#include "pugixml.hpp"

using std::ifstream;
using std::ios;
using std::string;
using std::wstring;

int main( int argc, char * argv[] )
{
    ifstream oFile;

    try
    {
        string sContent;

        oFile.open ( "../config-sample.xml", ios::in );

        if( oFile.is_open() )
        {
            wchar_t wsBuffer[128];

            while( oFile.good() )
            {
                oFile >> sContent;
                mbstowcs( wsBuffer, sContent.c_str(), sizeof( wsBuffer ) );
              //wprintf( wsBuffer );// Same result as wcout.
                wcout << wsBuffer;
            }

            Sleep(100000);
        }
        else
        {
            throw L"Failed to open file";
        }
    }
    catch( const wchar_t * pwsMsg )
    {
        ::MessageBox( NULL, pwsMsg, L"Error", MB_OK | MB_TOPMOST | MB_SETFOREGROUND );
    }

    if( oFile.is_open() )
    {
        oFile.close();
    }

    return 0;
}

一定有一些我不了解编码的东西。

4

4 回答 4

2

宽字符串并不意味着 UTF-8。事实上,恰恰相反:UTF-8 表示 Unicode 转换格式(8 位);这是一种在 8 位字符上表示 Unicode 的方法,所以你的正常chars. 您应该将其读入普通字符串(不是宽字符串)。

宽字符串使用wchar_t,在 Windows 上是 16 位。操作系统使用 UTF-16 来实现其“宽”功能。

在 Windows 上,UTF-8 字符串可以使用MultiByteToWideChar.

于 2013-09-07T22:03:44.530 回答
2

问题是 ambstowcs实际上并不使用 UTF-8。它使用旧式的“多字节代码点”,与 UTF-8 不兼容(尽管在技术上 [我相信] 可以定义 UTF-8 代码页,但在 Windows 中没有这样的东西)。

如果要将 UTF-8 转换为 UTF-16,可以使用MultiByteToWideChar,codepageCP_UTF8.

于 2013-09-07T22:12:36.843 回答
0

我制作了一个 C++char_t容器,最多可容纳 6 个 8 位 char_t 将其存储在std::vector. 将其转换为和从wchar_t或附加到std::string.

在这里查看: 在 Github 上查看 UTF-8_String 结构

#include "UTF-8_String.h" //header from github link above

iBS::u8str  raw_v;
iBS::readu8file("TestUTF-8File.txt",raw_v);
std::cout<<raw_v.str()<<std::endl;

这是在上面标题中喜欢的 u8char 结构中将 wchar_t 转换为 uint32_t 的函数。

    #include <cwchar>

    u8char& operator=(wchar_t& wc)
    {
        char temp[6];
        std::mbstate_t state ;
        int ret = std::wcrtomb((&temp[0]), wc, &state);
        ref.resize(ret);
        for (short i=0; i<ret; ++i) 
            ref[i]=temp[i];
        return *this;
    };
于 2016-05-17T16:44:23.263 回答
0

我发现wifstream效果很好,即使在 Visual Studio 调试器中正确显示 UTF-8 单词(我正在阅读繁体中文单词),来自这篇文章

#include <sstream>
#include <fstream>
#include <codecvt>

std::wstring readFile(const char* filename)
{
    std::wifstream wif(filename);
    wif.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>));
    std::wstringstream wss;
    wss << wif.rdbuf();
    return wss.str();
}
 
//  usage
std::wstring wstr2;
wstr2 = readFile("C:\\yourUtf8File.txt");
wcout << wstr2;
于 2021-04-15T15:28:11.823 回答