C++ C++;/wcout/UTF-8

C++ C++;/wcout/UTF-8,c++,windows,encoding,utf-8,C++,Windows,Encoding,Utf 8,我正在读取一个UTF-8编码的unicode文本文件,并将其输出到控制台,但显示的字符与我用来创建该文件的文本编辑器中的字符不同。这是我的密码: #define UNICODE #include <windows.h> #include <iostream> #include <fstream> #include <string> #include "pugixml.hpp" using std::ifstream; using std::i

我正在读取一个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;
}
#定义UNICODE
#包括
#包括
#包括
#包括
#包括“pugixml.hpp”
使用std::ifstream;
使用std::ios;
使用std::string;
使用std::wstring;
int main(int argc,char*argv[])
{
If文件流;
尝试
{
字符串内容;
oFile.open(“../config sample.xml”,ios::in);
如果(文件的)是打开的()
{
wchar_t wsBuffer[128];
而(of ile.good())
{
文件>>内容;
mbstowcs(wsBuffer,scocontent.c_str(),sizeof(wsBuffer));
//wprintf(wsBuffer);//结果与wcout相同。

wcout宽字符串并不意味着UTF-8。事实上,它恰恰相反:UTF-8意味着Unicode转换格式(8位);它是一种在8位字符上表示Unicode的方法,因此您的普通
char
s。您应该将其读入普通字符串(而不是宽字符串)

宽字符串使用
wchar\u t
,在Windows上为16位。操作系统使用UTF-16实现其“宽”功能


在Windows上,可以使用将UTF-8字符串转换为UTF-16。

宽字符串并不意味着UTF-8。事实上,情况正好相反:UTF-8意味着Unicode转换格式(8位);它是一种在8位字符上表示Unicode的方法,因此您的普通
字符
s。您应该将其读入普通字符串(而不是宽字符串)

宽字符串使用
wchar\u t
,在Windows上为16位。操作系统使用UTF-16实现其“宽”功能


在Windows上,可以使用将UTF-8字符串转换为UTF-16。

问题是,
mbstowcs
实际上没有使用UTF-8。它使用了一种较旧的“多字节码点”,这与UTF-8不兼容(虽然从技术上讲可以定义UTF-8码页,但Windows中没有这样的东西)


如果您想将UTF-8转换为UTF-16,您可以使用
CP\u UTF8的
codepage

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


如果您想将UTF-8转换为UTF-16,可以使用<代码>代码> <代码> CPUTF8 .< /P> < P>我制作了一个C++<代码> CARUT<<代码>容器,它保存在6个8位字符中,在一个<代码> STD::vector < /代码>中。将它转换为“代码> WHARCHYT”或将其附加到<代码> STD::String

在这里查看:

#包括上面github链接中的“UTF-8_String.h”//header
iBS::u8str原始值;
iBS::readu8file(“TestUTF-8File.txt”,原始文件);

STD::CUT< P>我制作了一个C++代码> CARYT 容器,它容纳6个8位字符,它存储在<代码> STD::vector < /代码>中。将它转换为“代码”>“WCARGYTT < /COD>”,或将其附加到<代码> STD::String < /C> > /P> 在这里查看:

#包括上面github链接中的“UTF-8_String.h”//header
iBS::u8str原始值;
iBS::readu8file(“TestUTF-8File.txt”,原始文件);

std::cout我发现
wifstream
工作得非常好,即使在visual studio中,调试器也能正确显示UTF-8单词(我正在阅读繁体中文单词),来自:

#包括
#包括
#包括
std::wstring读取文件(常量字符*文件名)
{
std::wifstream wif(文件名);
imbue(std::locale(std::locale::empty(),新std::codevt_utf8));
std::wstringstream wss;

wss我发现
wifstream
工作得非常好,即使在visual studio中,调试器也能正确显示UTF-8单词(我正在阅读繁体中文单词),来自:

#包括
#包括
#包括
std::wstring读取文件(常量字符*文件名)
{
std::wifstream wif(文件名);
imbue(std::locale(std::locale::empty(),新std::codevt_utf8));
std::wstringstream wss;

wss所以我需要将我的UTF-8文本转换为UTF-16,以便windows可以使用它?大多数接受字符串的函数都可以用A或W作为后缀,以指示字符串是字符字符串还是wchar___t字符串。如果您的API只有宽字符串变量,则需要转换。否则,这取决于函数是否接受UTF-8(我对此不确定)。如果没有,您仍然需要转换,是的。因此,我需要将我的UTF-8文本转换为UTF-16,以便windows可以使用它?大多数接受字符串的函数都可以用A或W作为后缀,以指示字符串是char字符串还是wchar_t字符串。如果您的API只有宽字符串变量,则是的,您需要转换。否则,这取决于我f函数是否接受UTF-8(我不确定)。如果不接受,您仍然需要转换,是的。谢谢,我试试这个!谢谢,我试试这个!
#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;
    #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;
    };
#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;