C++ 从C+中的文件中读取和打印UTF-8符号+;

C++ 从C+中的文件中读取和打印UTF-8符号+;,c++,windows,utf-8,C++,Windows,Utf 8,我遇到了一个问题,在互联网上找不到答案。尽管我发现了许多类似的问题,但没有一个答案对我有用。我正在Windows 10上使用Visual Studio 2015 因此,我的部分代码是: wstring books[50]; wstring authors[50]; wstring genres[50]; wstring takenBy[50]; wstring additional; bool taken[50]; _setmode(_fileno(stdout), _O_U8TEXT); wi

我遇到了一个问题,在互联网上找不到答案。尽管我发现了许多类似的问题,但没有一个答案对我有用。我正在Windows 10上使用Visual Studio 2015

因此,我的部分代码是:

wstring books[50];
wstring authors[50];
wstring genres[50];
wstring takenBy[50];
wstring additional;
bool taken[50];
_setmode(_fileno(stdout), _O_U8TEXT);
wifstream fd("bookList.txt");
i = 0;
while (!fd.eof())
{
    getline(fd, books[i]);
    getline(fd, authors[i]);
    getline(fd, genres[i]);
    getline(fd, takenBy[i]);
    fd >> taken[i];
    getline(fd, additional);
    i++;
}

我需要的是用C++读取一个UTF-8编码的文本文件。但是,当我读取文件时,这些宽字符串被更改,当我打印它们时,输出文本是完全不同的

输入:

ąęę

输出:

ÄÄÄ


我如何避免它并正确阅读课文

(可能)不在宽字符串中。了解。UTF-8使用8位字节(有时有几个字节)对Unicode字符进行编码。因此在C++中,Unicode字符从1到6字节的序列中解析(即<代码> char < /Code > -s)。 您需要一些UTF-8解析器,而C11或C++11标准不提供任何解析器。所以你需要一些外部库。查看(这是一个简单的C UTF-8解析库)或其他内容(、、…)。您可以决定将UTF-8解析并转换为wide(使用
u32string
-s和
char32\u t
)并向后转换,或者您最好决定在UTF-8内部工作(使用
std::string
char

因此,您将解析和打印
char
-s的序列(使用UTF-8编码),并且您的程序将使用纯
std::string
-s和纯
char
-s(不是
std::wstring
wchar\u t
),但处理UTF-8序列…

这很容易:

#定义BOOST_SPIRIT_UNICODE
#包括
#包括
#包括
使用名称空间boost::spirit;
int main()
{
std::串入(“ąę”);
std::字符串输出;
qi::parse(in.begin()、in.end()、+unicode::char\uz、out);
std::cout out;
auto ok=qi::parse(in.begin()、in.end(),
*(
+(unicode::char\uqi::eol)>>qi::eol/*book*/
>>+(unicode::char\uqi::eol)>>qi::eol/*作者*/
>>+(unicode::char\uqi::eol)>>qi::eol/*takenBy*/
),
),;
如果(确定)
{
用于(自动输入:输出(&T)
{
标准::字符串书,作者,takenBy;
标准::tie(书籍、作者、takenBy)=条目;

这样我们就不必简单地重复所有“对你不起作用”的答案了,也许您可以进一步说明为什么现有解决方案不适用?@LightnessRacesinOrbit正如我所说,我需要从文件中获取并打印UTF-8字符,但当我尝试在其他地方给出的答案和建议时,它们要么根本不起作用,要么没有完成我需要它完成的任务,例如,正如我已经编写的,字符串丢失UTF-8字符,我想知道如何避免丢失。更新您的问题请不要发表评论。您能说明您运行的平台吗?Unicode仍然有一些平台依赖项。如果您使用Windows控制台,请查看它的OT,但请注意
while(!fd.eof())
可能导致。读到C11或C++11标准没有提供任何
#define BOOST_SPIRIT_UNICODE
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>

using namespace boost::spirit;

int main()
{
    std::string in("ąčę");
    std::string out;
    qi::parse(in.begin(), in.end(), +unicode::char_, out);
    std::cout << out << std::endl;
}
#define BOOST_SPIRIT_UNICODE
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>

using namespace boost::spirit;

int main()
{
    std::string in("Book_1\nAuthors_1\nTakenBy_1\n"\
                   "Book ąčę\nAuthors_2\nTakenBy_2\n");
    std::vector<
        std::tuple<
            std::string, /* book */
            std::string, /* authors */
            std::string  /* takenBy */
        > 
    > out;
    auto ok = qi::parse(in.begin(), in.end(),
                        *(
                               +(unicode::char_ - qi::eol) >> qi::eol /* book */
                            >> +(unicode::char_ - qi::eol) >> qi::eol /* authors */
                            >> +(unicode::char_ - qi::eol) >> qi::eol /* takenBy */
                        ),
                        out);
    if(ok)
    {
        for(auto& entry : out)
        {
            std::string book, authors, takenBy;
            std::tie(book, authors, takenBy) = entry;
            std::cout << "book: "    << book    << std::endl
                      << "authors: " << authors << std::endl
                      << "takenBy: " << takenBy << std::endl;
        }
    }
}