C++ 从C+中的文件中读取和打印UTF-8符号+;
我遇到了一个问题,在互联网上找不到答案。尽管我发现了许多类似的问题,但没有一个答案对我有用。我正在Windows 10上使用Visual Studio 2015 因此,我的部分代码是: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
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;
}
}
}